2011-08-08 147 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