0

SQL クエリの最適化に関する記事では、OR の代わりに Union を使用することを提案しています。

OR の代わりに Union を利用する


少なくとも MySQLの OR 状況でインデックスを使用すると、速度の利点が失われます。したがって、インデックスが適用されていますが、これは役に立ちません。
1 SELECT * FROM TABLE WHERE COLUMN_A = 'value' OR
COLUMN_B = 'value'

一方、このようなユニオンを使用すると、インデックスが利用されます。
1- SELECT * FROM TABLE WHERE COLUMN_A = '値'
2- UNION 3- SELECT * FROM
TABLE WHERE COLUMN_B = '値'

この提案はどの程度真実ですか? OR クエリを Union に変更する必要がありますか?

4

2 に答える 2

0

これは原則としてお勧めしません。ここには MySQL がインストールされていないため、生成された実行計画を確認できませんが、確かに Oracle では計画が大きく異なり、「OR」計画は「UNION」計画よりも効率的です。(基本的に、「UNION」は 2 つの SELECT を実行してから結果をマージする必要があります。「OR」は単一の SELECT のみを実行する必要があります)。「UNION ALL」プランでさえ、「OR」プランよりもコストが高くなります。「OR」に固執します。

できる限り明確で単純なコードを書くことを強くお勧めします。私にとって、それは「UNION」ではなく「OR」を使用する必要があることを意味します。何年にもわたって、何かを「事前に最適化」しようとすること、つまりパフォーマンスの問題が発生する場所を推測し、それらの問題を回避するようにコーディングしようとすることは時間の無駄であることがわかりました。コードは最も厄介な場所で多くの時間を費やす傾向があり、コードを実行して初めてそれらを見つけることができます。かなり前に、このコンテキストで役立つとわかった 3 つのルールを学びました。

  1. 実行する場合は作成します。
  2. 正しく実行してください。
  3. すぐに実行できるようにします。

最適化は文字通り、あなたがすべき最後のことです。

共有してお楽しみください。


フォローアップ: 「OR」が別の列を参照していることに気付きませんでしたが (私の悪い点です)、「シンプルに保つ」という私のアドバイスは今でも有効です。

于 2012-04-17T11:16:24.157 に答える
0

インデックスを電話帳の名前のように考えると役立ちます。電話帳には、自然に名前順に並べられたインデックスがあると言えます。つまり、John Smith のすべての名前を検索したい場合、それを見つけるのにほとんど、またはまったく時間がかかりません。電話帳の S セクションを開いて、Smith の検索を開始するだけです。

ここで、John Smith という名前または電話番号 863-2253 のエントリを電話帳で探すように言ったらどうなるでしょうか。すぐにはできませんよね?正確な答えを得るには、John Smith を検索するための電話帳と、電話番号で名前を見つけるために電話番号で並べ替えられた別の電話帳が必要です。

おそらく、より洗練されたエンジンは、この分離の必要性を認識して自動的に実行できますが、明らかに MySQL はそうではありません。このようにするのは面倒に思えるかもしれませんが、レコード数の多いテーブルの違いは顕著です。

于 2012-04-17T11:17:08.933 に答える