ホームページ >データベース >mysql チュートリアル >INNER JOIN 条件で「OR」を使用すると常に SQL パフォーマンスが低下しますか?
SQL INNER JOIN
と OR
: パフォーマンスのボトルネック
最近のパフォーマンス最適化の取り組みにより、OR
条件内での INNER JOIN
演算子の使用という重大な問題が明らかになりました。 次のクエリは問題の例です:
<code class="language-sql">SELECT mt.ID, mt.ParentID, ot.MasterID FROM dbo.MainTable AS mt INNER JOIN dbo.OtherTable AS ot ON ot.ParentID = mt.ID OR ot.ID = mt.ParentID</code>
このクエリは遅いことが判明しました。 LEFT JOIN
を使用して書き直すとパフォーマンスが劇的に向上しました:
<code class="language-sql">SELECT mt.ID, mt.ParentID, CASE WHEN ot1.MasterID IS NOT NULL THEN ot1.MasterID ELSE ot2.MasterID END AS MasterID FROM dbo.MainTable AS mt LEFT JOIN dbo.OtherTable AS ot1 ON ot1.ParentID = mt.ID LEFT JOIN dbo.OtherTable AS ot2 ON ot2.ID = mt.ParentID WHERE ot1.MasterID IS NOT NULL OR ot2.MasterID IS NOT NULL</code>
改訂されたクエリは数秒で実行され、大幅に改善されました。 これにより、OR
条件での JOIN
の一般的な使用について懸念が生じます。
JOIN の OR
が遅い理由
中心的な問題は、OR
条件内の JOIN
によって、SQL Server オプティマイザーが効率的な HASH
または MERGE
結合を利用できないことです。これらの最適化された結合方法は、通常、クエリを高速に実行するために非常に重要です。 OR
条件により、サーバーはクエリが 2 つの別個の等価結合と等価であることを認識できなくなります:
<code class="language-sql">SELECT * FROM maintable m JOIN othertable o ON o.parentId = m.id UNION SELECT * FROM maintable m JOIN othertable o ON o.id = m.parentId</code>
これにより、SQL Server は効率の低い実行プランを選択することになり、パフォーマンスが低下します。
ベスト プラクティス: OR
条件では JOIN
を避ける
厳密に禁止されているわけではありませんが、OR
条件で JOIN
を使用すると、最適化が妨げられ、パフォーマンスの低下につながることがよくあります。 複数の結合条件の場合、個別の等結合 (上記の LEFT JOIN
と UNION
、または LEFT JOIN
と CASE
ステートメント) は通常、優れたパフォーマンスを提供します。 これにより、クエリ オプティマイザーは最も効率的なアルゴリズムを活用できるようになります。
以上がINNER JOIN 条件で「OR」を使用すると常に SQL パフォーマンスが低下しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。