2011-08-08 28 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' 

であり、結果は、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 

としてcmp_dealsテーブルの各項目でソートすることができますこれは "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

おかげで、私はすべてのそれらの二重のID(数値と人間が読める)のファンだと言うことはできません。実際にvarcharのバージョンが必要ない場合は、それらを削除してください。

変更cmp_tarrifs.IDを参照するcmp_deals.tarrif_id外部キー(すなわち、それInnoDBを使用してINTし、もし作る、実際に外部キー制約を作成します)。

少なくとも、cmp_tariffs.IDを主キーとし、オプションでcmp_tariffs.tariff_idをユニークなインデックスにします。

関税率表にゼロのインデックスがあるということは、結合を完了するためにテーブルスキャンを行う必要があることを意味します。

+0

ご回答いただきありがとうございます。そこにはたくさんの情報があります。それを最大限に活用しようとします。私のポストを編集してより見やすくしてくれてありがとう@Phil - 苦労しました! – Simon

+0

cmp_tariff.tariff_idにインデックスを作成しました。 – Simon

+0

データベースタイプはMyISAMです。つまり、外部キーを作成できません。私は今、varchar(30)の代わりに短い主キー(INT)を参照する方が良い理由を理解していますが、残念ながらtariff_idは2つのテーブル間の共通リンクです。両方のテーブルのIDとIDは、自動インクリメント値です。正直言って、なぜ私は最初にそれらを置くのか分かりません。私が提案について述べたコメントを考慮に入れて、私はそれが正しいと言うことを訂正しています。 – Simon