2011-09-30 8 views
0

私は以下のクエリは、その返還を知っている:T1がT2に多くのT2を保持し、T2に条件が保持されている場合、T1からT2ではなくT2からT1に結合する方が効率的ですか?それとも同じですか?

SELECT `cimgs`.* 
FROM `cimgs` 
INNER JOIN `cimgs_tags` ON `cimgs_tags`.`cimg_id` = `cimgs`.`id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

SELECT `cimgs`.* 
FROM `cimgs_tags` 
INNER JOIN `cimgs` ON `cimgs`.`id` = `cimgs_tags`.`cimg_id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

しかし、一見、私は二番目の条件を確認したときに最初のものは、条件をチェックする前に、各タグにcimgsテーブルを複製することを言うだろう...

MySQLがこれを自動的に検出して最適化するかどうかわかりませんが、これらの2つのクエリのパフォーマンスは同じですか?

+1

... –

+0

はまあ、あなたがテストするためのベンチマークを行う必要があり、「どのように」を決定し、しかし、私は最初の1何を読んでから最適化の適用は、結合を最も効率的に並べ替えることです。ちょうど2つのテーブルの場合、私はそれがオプティマイザなしでさえ違いがあるとは想像できません。 –

答えて

3

クエリオプティマイザがこれを行います。インデックスの統計情報を使用します。最新の情報はANALYSE TABLEです。あなたはSTRAIGHT_JOINを使用してテー・ジョイン・オーダーを強制することができます。また、特定のインデックスの使用を強制することもできます。

あなたは説明できます:

EXPLAIN SELECT `cimgs`.* 
FROM `cimgs` 
INNER JOIN `cimgs_tags` ON `cimgs_tags`.`cimg_id` = `cimgs`.`id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

EXPLAIN SELECT `cimgs`.* 
FROM `cimgs_tags` 
INNER JOIN `cimgs` ON `cimgs`.`id` = `cimgs_tags`.`cimg_id` 
WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

は違いを確認します。

Offcourse、LEFT JOINまたはRIGHT JOINの場合、意味的な違いがあります。

+0

ありがとう!私はこれが多くの記録を持つ将来問題を引き起こす可能性があることを非常に心配していました。 – Zequez

0

私はthis question

は、あなたの質問に答えると信じています。

「内部結合、順序は重要ではありませんください。
外の場合は、順序が問題ありません参加する。
あなたが特定の順序を強制したい場合、あなたはSTRAIGHT_JOINを使用することができます。」

3

INNER JOINSからは関係ありません。同じやり方でWHERE句の順序

WHERE `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) AND (cimgs.id != 1) 

WHERE (cimgs.id != 1) AND `cimgs_tags`.`tag_id` IN (1, 2, 3, 4, 5) 
  • オプティマイザはこの
  • SQLは、手続き型ではない宣言型であることを知っているどちらも行いません。それはあなたが言う、「何を」とオプティマイザが
  • オプティマイザの仕事です
+1

あなたは「what」と言って、オプティマイザは「how」を決めます。それが働くはずです。実際の生活では、オプティマイザが時々恐ろしい間違いを引き起こし、あなたはそれをちょっと蹴る必要があります。 – Thilo

+0

@Thilo:クエリがより複雑になるので、はい。通常、オプティマイザはコストベースなので、完璧なプランを見つけるのに2週間かかります。それは当然ではないかもしれない。 2番目の推測オプティマイザは、当時のデータ、インデックス、配信などでのみ機能し、 – gbn

+0

は「その時点でデータ、インデックス、配信などのために働いていますが、持続することはできません。はい。それは難しい問題です。私は、オプティマイザが複雑なクエリやスキューされたデータに対して適切になるとは思っていません。私の問題は、宣言的なアプローチが失敗した時点で、ヒントなどでシステムを「強制的に動作させる」のが難しいことです。あなたは明示的に必要とする実行計画を書き留めておいて、いつかSQLの代わりに「プログラマチックな」代替案を用意するのがいいでしょう。悪い実行計画がわずか2倍遅くても、これは本当の問題にはなりませんが、x1000になる可能性があります。 – Thilo

関連する問題