2011-08-08 95 views
0

我想优化我的网站,并会感激一些帮助。mySql加入优化查询

该网站是一个手机比较网站,查询是显示特定手机的优惠。数据位于2个表中,cmp_deals表有931000个条目,cmp_tariffs表有2600个条目。通用字段是tariff_id。

###The deals table### 
id int(11) 
hs_id varchar(30) 
tariff_id varchar(30) 
hs_price decimal(4,2) 
months_free  int(2) 
months_half  int(2) 
cash_back decimal(4,2) 
free_gift text 
retailer_id  varchar(20) 

###Deals Indexes### 
hs_id INDEX 430  Edit Drop hs_id 
months_half  INDEX 33  Edit Drop months_half 
months_free  INDEX 25  Edit Drop months_free 
hs_price INDEX 2223 Edit Drop hs_price 
cash_back INDEX<br/> 


###The tariff table### 
ID int(11) 
tariff_id varchar(30) 
tariff_name  varchar(255) 
tariff_desc  text 
anytime_mins int(5) 
offpeak_mins int(5) 
texts int(5) 
line_rental  decimal(4,2) 
cost_offset  decimal(4,2) 

没有索引

初始查询是

SELECT * FROM `cmp_deals` 
LEFT JOIN `cmp_tariffs` USING (tariff_id) 
WHERE hs_id = 'iphone432gbwhite' 

,然后将结果可通过在cmp_deals表中的各种物品,如cash_back或free_gift

SELECT * FROM `cmp_deals` 
LEFT JOIN `cmp_tariffs` USING (tariff_id) 
WHERE hs_id = 'iphone432gbwhite' 
ORDER BY hs_price DESC 
LIMIT 30 

进行排序这是我运行“EXPLAIN”命令时的结果,但我并不真正了解结果。

id select_type  table type possible_keys key  key_len  ref  rows Extra<br/> 
1 SIMPLE cmp_deals ref  hs_id hs_id 92 const 179  Using where; Using temporary; Using filesort<br/> 
1 SIMPLE cmp_tariffs  ALL  NULL NULL NULL NULL 2582 

我想知道,如果我以最有效的方式做这些查询,因为查询平均在2秒以上。

在此先感谢

+0

如果您有使用此JOIN的查询,则至少应在两个表上有'tariff_id'索引。 –

+0

对于这个特定的查询,您可能会受益于'(hs_id,tariff_id)' –

+0

上的附加索引,并且对'hs_price'有一个索引,因此ORDER BY/LIMIT很快。 –

回答

1

不能说我所有的双标识(数字和人类可读)的粉丝。如果您实际上不需要varchar版本,请将其删除。

更改外键cmp_deals.tarrif_id引用cmp_tarrifs.ID(即,使之成为INT如果使用InnoDB,实际上创建外键约束)。

至少使cmp_tariffs.ID成为主键和可选的cmp_tariffs.tariff_id唯一索引。

资费表中零索引意味着它必须执行表扫描才能完成连接。

+0

感谢您的回复。那里有很多信息;将尝试充分利用它。感谢@Phil编辑我的文章,使其更加可观 - 我挣扎着! – Simon

+0

我在cmp_tariff.tariff_id上创建了一个索引。 – Simon

+0

数据库类型是MyISAM,这意味着我无法创建外键。我现在明白了为什么最好引用较短的主键(INT)而不是varchar(30),但不幸的是,tariff_id是两个表之间的公共链接。两个表的ID和ID都是自动增量值 - 说实话,我不知道为什么我把它放在第一位。考虑到我对这些建议提出的意见,我是否正确地说,该查询速度与其获得的速度一样快? – Simon