2013-10-29 3 views
5

に選択(A、B)にAの(A、B)を選択し、B(A、B)対をインナーに参加しますか? 同じ結果を出力します.1つはwhere inの中で条件を実行し、もう1つはinner joinの中にあるとします。は間の最良のクエリが2の学位論文は何mysqlの

select uv.* from version v inner join user_version uv ON v.id=uv.version_id 
WHERE (v.number, v.master_id) IN (
select max(v.number) as number, v.master_id 
    from version v inner join user_version uv ON v.id=uv.version_id group by v.master_id); 

select * from user_version uv 
    inner join version v on v.id=uv.version_id and v.number 
    inner join (
     select uv2.user_id, max(v2.number) maxNumber, v2.master_id master_id, v2.id version_id from version v2 
     inner join user_version uv2 on v2.id=uv2.version_id group by v2.master_id) test 
    on test.master_id=v.master_id and test.maxNumber=v.number ; 

私は例とsqlfiddle作成しました:http://sqlfiddle.com/#!2/76001/62 (アイデアは、特定のユーザーにリンクされている「マスター」エンティティの最大のバージョンを取得することである)

あなたは

おかげ

(私はそう、私は窓の機能を使用することはできません、MySQLを使用しています)他のアイデアを持っている場合
+0

、第二のような「非相関サブクエリのソリューションはその代替案よりも速くなる傾向があります。あなたの質問はもう少し複雑ですが、私はその原則が成立していると思います。 – Strawberry

答えて

3

これはこの質問に答えるのが容易ではありません。 MySQLはIN (<static values list>)IN (<subquery>)different queriesと扱います。第二は= ANY()に等しいながら最初のものは(.. OR = .. OR =など)範囲比較に等しく、 - それは同じではありません。 ANY()でクエリが発生しますサブクエリでIN使用し、MySQLはサブクエリが独立しており、値の静的リストを返す場合でも、そのためにインデックスを使用しません:だから、短いと言っています。悲しいが本当。 MySQLはそれを予測できないので、たとえ明白であってもインデックスは使用されません。 JOIN(すなわち、IN (<subquery>)を書き換えます)を使用する場合は、可能であれば、MySQLはJOINのインデックスを使用します。パーティションを使用する場合

次に、第二の場合は、約JOININであってもよいです。 JOINを使用する場合、悲しいことですが - MySQLは一般的にJOINのパーティションを予測することができず、パーティション全体を使用します。 IN (<static list>)JOINを交換するEXPLAIN PARTITION画像を変更します:MySQLはIN句の中に指定された範囲から値を選択するために必要とされているパーティションのみを使用します。しかし、これもIN (<subquery>)では機能しません。

結論として、MySQLがINサブクエリをどのように処理しているかについて言及すると、悲しいことですが、普通はJOINに置き換えることはできません(パーティション化の場合)。したがって、一般的な解決策は次のようになります。のメインクエリとは別のサブクエリ静的な値リストを返す独立したサブクエリについて言えば、それがベストプラクティスです。その値リストをIN(<static list>)に置き換えて利益を得ることができます:MySQLはインデックスを使用します。それらから実際に必要とされるものが使用されます。一般的に

+0

あなたは、最初のリクエストはmaster_id/numberのインデックスを使用せず、2番目のリクエストはtest.master_id = vのフィルタなしで各行のselectに一致するすべての結果を返します。 master_id条件? (この場合、PARTITIONのアイデアは私にとっては本当に明確ではありません) – Quentin

+0

最初のものは 'IN'サブクエリのインデックスを使用しません –

関連する問題