0

MYSQL では、あまり変更したくない Wordpress プラグインのコードが次のクエリを実行しています。

SELECT * WHERE cond1 AND (field1 = val1 OR field2 = val2)

ただし、val1 と val2 にインデックスがあるにもかかわらず、実行速度は非常に遅くなります。(遅いクエリ ログは、すべての行をスキャンすることを確認します。)MYSQL に、式を常に次の同等のより高速な形式に展開する必要があることを示唆できますか?

SELECT * WHERE cond1 AND (field1 = val1)
UNION
SELECT * WHERE cond1 AND (field2 = val2)

これにより、スキャンされる行数が大幅に削減されるため、パフォーマンスが大幅に向上します。私も同じことを疑問に思います

SELECT * WHERE cond1 AND (field1 in (val1, val2))

ありがとう!

編集: テーブルに関する情報とクエリの説明はhttp://pastebin.com/Qd1ZaVKDにありますが、一貫性がないようです。myphpadmin からクエリを実行すると、低速のクエリ ログ エントリが生成される場合と生成されない場合があります。他のユーザーがそのような行を引き起こしているときに引き続き生成されたとしてもです。

4

1 に答える 1

1

それは最初に に依存し、次にその条件の下でcond1のカーディナリティにfield1依存します:field2

  1. 列と定数値との直接比較が必要な場合(つまり、インデックスが解決に役立つ場合)、 and/orcond1を使用した複合インデックスが役立つ場合があります (以下を参照)。field1field2

    関数やorcond1などの他の操作を適用するなど、列の操作が必要な場合、インデックスは役に立ちません。ただし、これらの例は両方とも、インデックスに適したものに書き直すことができることに注意してください。my_int + 5 = 3DATE(my_timestamp) > NOW()

    • my_int = 3 - 5my_int = -2、これは明らかに;と同等です。と

    • my_timestamp >= CURDATE() + INTERVAL 1 DAY.

  2. カーディナリティが比較的高い (つまり、多くのレコードをすばやく区別できる) インデックスを作成するだけの価値があります。それ以外の場合は、テーブルの書き込み操作が遅くなり、追加のストレージとメモリ スペースが消費される一方で、完全なテーブル スキャンよりも少し良くなります。cond1field1およびのカーディナリティだけでなく、各フィールドのカーディナリティも考慮してfield2ください。cond1

    それらがすべて高いカーディナリティを持っていると仮定すると、最善の策は、とのそれぞれに 2 つの複合インデックスを使用してindex_merge(ユニオン アクセス)を実現することです。(cond1, field1)(cond1, field2)

于 2012-11-11T23:17:03.873 に答える