sql >> データベース >  >> RDS >> PostgreSQL

最も自然なクエリ(つまり、(LEFTJOINの代わりに)INNER JOINを使用する)が非常に遅いのはなぜですか

    (指示どおり、問題が解決したので、コメントの一部を回答に入れています)

    EXISTS式をIN式に変換します。

    この場合、クエリは「裏返し」から効果的に評価され、最も制限的な要素である全文検索ルックアップを含むクエリから開始されるため、これはより適切に機能します。そのクエリは、の値ごとに1回「内部」クエリを呼び出すのではなく、外部クエリの主キー(WHERE x in(SELECT X ...))に対して直接検索できる行の小さなセットを返します。外側のクエリ(または、正しく読んでいる場合は、元のケースのすべての値)。ここでのEXISTSメソッドは、ネストされたループ(別の値ごとに1つのクエリの1つの評価)とハッシュ結合を使用したINメソッド(ほとんどではないにしても、多くの場合、はるかに効率的な実行メソッド)になります。

    EXISTSメソッドでは、それぞれが少なくとも3,000回実行される4つのネストされたループがあることに注意してください。そのコストは合計されます。直接の比較ではありませんが、アプリケーションコードのFORループと同じようにネストされたループを扱うことができます。内部ループを呼び出すたびに、big-Oの見積もりは1桁上がります:O(n)からO(n ^ 2)からO(n ^ 3)など。

    ハッシュ結合は、2つの配列が同時にステップスルーされ、両方で操作が実行されるマップに似ています。これはほぼ線形です(O(n))。これらは、O(n)からO(2n)、O(3n)などになるように、追加としてネストされていると考えてください。

    ええ、ええ、まったく同じではないことはわかっていますが、要点は、ネストされたループが複数あると、通常、クエリプランが遅くなり、2つのbig-Oスタイルを比較すると認識しやすくなると思います。

    ネストされたループとEXISTS自体は悪ではありませんが、最終的にすべてに影響を与える基本フィルター条件(たとえば、質問の全文検索)、IN式(または一部)が存在するほとんどの場合 場合によっては、適切なJOIN)により、はるかに効率的な計画が得られます。



    1. テーブル名が別のテーブルのフィールドであるMySQL結合テーブル

    2. SQLServerのトリガーのリストを返す

    3. MySQL LAG/LEADの問題

    4. SQL Server Data Tools は SQL Server 2008 SSIS と連携できますか?