2012-03-22 9 views
13

私はINTのカラムを持つ200kエントリのテーブルを持っています。クエリをより速くするためのインデックスを作成したい。これは私が実行したいクエリです:SELECT A,B,C,D,E FROM table WHERE A=23 and (B=45 or C=43)。私は次のインデックスを作成しました:BACDCABCMySQL。 "OR"クエリのインデックスを作成する

EXPLAINコマンドでは、MySQLがインデックスACDを選択したことがわかりました。だから私はテーブルをより多くの値で埋めることを続けました、そして、私は上記のインデックス間でMySQLが切り替えていることに気付きました(常に同じではない)。

さまざまなインデックスを持つため、パフォーマンス上の問題が発生し、このテーブルには、すべてのインデックスが意味のある別の列を必要とする他のクエリによってアクセスされることが想定されます。

私はUSE INDEX()を知っていますが、正しいインデックスを選択するためにMySQLを信頼する必要があるかどうかを理解したいと思います。

+2

「このテーブルは、すべてのINDEXが意味を持つ異なる列を必要とする他のクエリによってアクセスされると考えることができます」とはどういう意味ですか?あなたはそのような質問のいくつかの例を挙げることができますか?また、 'SHOW INDEXES FROM table'クエリの出力を教えてください。 A、AB、ACの索引は確かに冗長です。これらはすでにACD/ABC、ABC、ACDの索引でそれぞれカバーされています。 MySQLがマルチカラムインデックスを扱う方法については、http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html – Daan

+0

でご覧になれます。クエリの例: 'BテーブルからBテーブルを取得するB = 12'。 さて、A、AB、AC(除外)は除外できます。しかし、それでもACDを使用する理由は説明されていません。 'D 'が' WHERE'ステートメントでさえもないとき。 –

+0

はい、それはちょっと不思議です: 'SHOW INDEXES FROM table'クエリの出力はなぜ起こっているのかを知るのに役立ちます:) – Daan

答えて

6

のために有用であろう。

INDEXを使用してこの問題を解決する方法は、2つの個別のクエリを作成するという結論に達しました。 SELECT A,B,C,D,E FROM table WHERE A=23 AND B=45INDEX ABCを使用し、次にSELECT A,B,C,D,E FROM table WHERE A=23 AND C=43INDEX ACDを使用します。これはすべて(...) UNION (...)を使って1つのステップで行うことができます。これは速くなり、INDEXだけを使用します。

1

Mysqlでは、複合インデックスの '左端'部分のみを使用できます。あなたの句が

WHERE A=1 AND B=2 

のように見えるところならばすなわち、その後、MySQLはAまたはABにインデックスを使用することができますが、ABは最高でしょう。 ACBインデックスが別の列で分割されているために使用できませんでした

WHERE句を使用すると、MySQLクエリエンジンが複数のインデックスを利用できるとは思われません。 ABACを作成し、FORCE INDEXを使用してどちらが高速かを確認します。

この場合、A列と他の列を参照しているため、3列の複合キーは役に立ちません。この種のキーは、クエリがORの代わりにANDを使用していた場合に役立ちます。 SQL文でORの、MySQLは単にACDあるAを含む第1のインデックスを取得しているのでABC上のインデックスが

WHERE A=1 AND B=2 AND C=3 
+2

はい、ANDで、ABCクエリを期待どおりに使用します。 'A'、' AB'を使うと 'AC'は以前のコメントで@Daanが述べたように重複するでしょう。 MySQLのドキュメントでは、「インデックスの一番左の接頭辞は、オプティマイザが行を検索するために使用できます。INDEX on(col1、col2、col3)では、(col1)、(col1、col2) (col1、col2、col3)」と表示されます。 –

+1

これはORに関する質問であり、ANDに関するものではありません。 –

関連する問題