web-dev-qa-db-ja.com

JOIN句でUSING構文を使用すると、特定の場合に最適化の障壁が発生する可能性がありますか?

USINGON節のFROMではなくSELECT構文に注意が必要ですクエリ は、特定の場合に最適化の障壁をもたらす可能性があります。

私はこのキーワードを意味します:

選択* 
 FROM a 
 JOIN b 使用 (a_id)

もっと複雑なケースでは。

コンテキスト: このコメント から この質問

私はこれをたくさん使用し、これまで何も気づかなかった。 テストケースの効果または任意のリンクを示すことに非常に興味があります)詳細情報へ。私の検索の努力は空になりました。

完璧な答えは、代替の結合句_ON a.a_id = b.a_id_-と比較した場合に、パフォーマンスが劣るUSING (a_id)を示すテストケースです。 実際に発生する可能性があります。

36

アーウィン:厳密な順序付けを引き起こすUSINGは、最適な計画が除外される多くのEdgeケースを作成する可能性があるという考えに同意します。私は最近、クエリに次のようなものがある人を助けました:

LEFT JOIN ( 
     a 
     JOIN b ON a.id = b.a_id
     JOIN c ON b.c_id = c.id
) ON a.id = something.a_id
LEFT JOIN (
     table1 t1
     JOIN table2 t2 ON t1.some_field = t2.other_field
     JOIN talbe3 t3 ON t2.yafield = t3.something_else
) ON ....
repeat a few more times

彼の場合、これらの結合ブロックの中で最悪の場合、約200k行のネストされたループ結合が約20k回(計算により)発生し、キーをインデックスにプッシュできなかったため、順次スキャンでした。つまり、カスケードプランの変更により、クエリ全体の実行に約3時間かかりました。左結合を分散することにより、キーがプッシュダウンされ、クエリが数秒で実行されます。もちろん、これは完全に等価ではありません。そのため、プランナはそれらを等価として扱うことができません。そのため、その計画をハッシュ結合として理解し、ネストされたループを実行するので、非常に時間がかかりました。

結合を特定の順序で厳密に通過させるときは常に、プランの実行時にキーフィルター情報がまだ利用できない場合があるため、後でクイックインデックススキャン/ハッシュ結合で何ができるかを紹介します。ネストされたループ/シーケンシャルスキャンでははるかに低速で実行する必要がある場合があるため、上記のフラグメントはすぐには同等ではありませんが、同じ問題を示しています。

12
Chris Travers