2011-11-02 12 views
0

単純な挿入と選択を超えたMySQLクエリの方が新しいので、これが完全に基本的なものであれば、私は事前に謝罪します。3テーブル結合最適化の提案?

多対多リレーションシップを持つデータベースがあり、3つのテーブルにわたってJOINクエリを作成しようとしています。それは私が書いたようにした最初の大きなテーブル/ビッグ・クエリーなので、私が読んだチュートリアルの内容を見ています。クエリはすべて正しい値を返しますが、遅い(0.25秒の平均を計算しますが、ローカルホスト上では約0.7をピークにしています)。

もっと効率的にする方法についてアドバイスをお持ちの方はいらっしゃいますか?私はインデックスを使って遊んできましたが、それは測定可能な効果がほとんどないようです。ここのリアルタイムキラーはORDER BYステートメントのようです。残念ながら、私はStack Overflowをトローしていても、それらを最適化することに全力を尽くすことはできません。

これが問題でクエリです:

SELECT a.d_id, cs_id, blg_id, d_name, d_slug, ct_id, a.cc_id 
FROM collection a 
JOIN designers b 
ON a.d_id = b.d_id 
JOIN designer2type c 
ON a.cc_id = c.cc_id 
WHERE cs_id = '3' 
ORDER BY d_name, ct_id ASC 

私が実行しても同様の平均を持っている以下のが、はるかにするために多くの時間がかかったいくつかの選択肢(サブクエリにいくつかのチュートリアルをコピーを試してみました高い最大:

SELECT collection.d_id, cs_id, blg_id, d_name, d_slug, collection.cc_id, c_url FROM collection, designers, c_image WHERE cs_id = '3' AND c_image.ci_id = collection.ci_id AND collection.d_id = designers.d_id ORDER BY d_name ASC 

これは、列区切りを表す||と説明している:

id || select_type || table || type || possible_keys || key || key_len || ref || rows || Extra 
1 || SIMPLE || a || ref || PRIMARY,d_id,cs_id || cs_id || 4 || const || 8403 || Using temporary; Using filesort 
1 || SIMPLE || b || eq_ref || PRIMARY || PRIMARY || 4 || test.a.d_id || 1  
1 || SIMPLE || c || ref || cc_id || cc_id || 4 || test.a.cc_id || 1 

そして、これらは、テーブル構造です:

CREATE TABLE `collection` (
`cc_id` int(8) NOT NULL AUTO_INCREMENT, 
`d_id` int(4) NOT NULL, 
`cs_id` int(3) NOT NULL, 
`cfw_id` int(2) NOT NULL, 
`c_id` int(8) NOT NULL, 
`ci_id` int(8) NOT NULL, 
`cg_id` int(1) NOT NULL, 
`blg_id` bigint(20) NOT NULL, 
PRIMARY KEY (`cc_id`), 
KEY `d_id` (`d_id`), 
KEY `cs_id` (`cs_id`), 
KEY `cfw_id` (`cfw_id`), 
KEY `c_id` (`c_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `designers` (
`d_id` int(4) NOT NULL AUTO_INCREMENT, 
`d_name` varchar(100) NOT NULL, 
`d_slug` varchar(100) NOT NULL, 
PRIMARY KEY (`d_id`), 
KEY `d_name` (`d_name`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=52782 ; 

CREATE TABLE `c_designer2type` (
`cd2t_id` int(8) NOT NULL AUTO_INCREMENT, 
`cc_id` int(8) NOT NULL, 
`ct_id` int(2) NOT NULL, 
`cd2t_desc` text NOT NULL, 
PRIMARY KEY (`cd2t_id`), 
KEY `cc_id` (`cc_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=57545 ; 

は、私は、これは、クエリの問題、インデックスの問題、またはテーブル構造の問題であるかはわかりません。あるいは、まったく問題ではないかもしれませんが、他の負荷のないローカルホスト上で1秒近くで最大値に達し、中程度の行だけが私の頭の中で高く見えます。いずれにせよ、このプロジェクトについては何も使用されていないので、必要に応じて何かを変更することができます。

誰もが、私はそれが非常に高く評価されます:)

おかげで、上の「CC_ID」にインデックスを追加タニア

答えて

0

てみてくださいクエストで間違っているかもしれない場所に任意の考え/アドバイスを持っている場合c_designer2typeテーブルでは、現在、クエリはテーブルを複数回スキャンして結合を行う必要があります。

これは主な選択基準であるため、 "cs_id"のインデックスを検討する価値があります。現在の設定では、 'collection'テーブルのすべての行が一致するかどうかを調べます。これは、 'cs_id'に妥当な数の値がある場合にのみ有効です。もし1,3しか持っていないのなら、それは本当に価値がありません。