先日、クエリで問題が発生しました。大きなデータセットの場合、約 10 秒かかりました。クエリは次のようになります。
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE a.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
OR b.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
これはかなり遅くなりました。ただし、次のように変更しました。
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE a.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
UNION ALL
SELECT a.* from Document as a
LEFT JOIN Waybill as b on a.waybill = b.id
WHERE b.enterpriseGuid = '763a3ac3-a3c7-4379-9735-2a4a96e87e5d'
2 つのクエリは基本的に同じ結果を生成しますが、これには約 0.01 秒かかりました。MySQL の公式ドキュメントを探したところ、興味深いコメントが見つかりました。
インデックスは、OR 状況で使用すると速度の利点を失います (4.1.10):
SELECT * FROM a WHERE index1 = 'foo' UNION SELECT * FROM a WHERE index2 = 'baar';
よりもはるかに高速です
SELECT * FROM a WHERE index1 = 'foo' OR index2 = 'bar';
だから、私の質問には3つの部分があります:
- 本番システム (つまり、データセットが非常に大きい場合) で選択クエリで OR 句を使用するのは本当に悪いことですか?
- この OR クエリは、何らかの方法でインデックスによって調整できますか? 現在、フィルター処理に使用するクエリの両方の列が実際にインデックス化されています。OR を UNION ALL と同じくらい高速に動作させるために、複雑な複合インデックスを作成できますか?
- これはベンダー固有の問題ですか、それとも Oracle や Postgresql でも同じ問題が発生するのでしょうか?