2011-02-02 5 views
1

MySQLのマルチカラムインデックスの順序に関する2つの相反する記述があります。 この投稿hereには、(b = value1 AND a = value2)を持つクエリに(a、b)インデックスも使用されるというコメントがあります。このFAQエントリhereは、(下に)まったく逆の(インデックスは使用されません)と言います。正しいものは何ですか? PostgreSQLはどうですか?それは同じように振る舞いますか?マルチカラムインデックスとSQLクエリの順

+1

私はMySQLのエキスパートではありませんが(SQL Serverと少しのOracleだけですが)、そのFAQの回答は非常に魅力的です(全テーブルスキャン* 3回* bどこの3つの条件のecause? Puuhlease!)。まともなSQLシステムでは、そのような種類のクエリに対してコンポジットインデックスを使用します(テーブルが非常に小さく、インデックスをまったく使用しない場合を除く) – TToni

答えて

2

まず、私は、銀の弾丸の答えはないと言っておきます。

(b = value1とa = value2)を満たすために、(a、b)複合インデックスのインデックスが使用されます。 ではなく、 WHERE句の "a"の前に "b"が表示されます。クエリエンジンは、aとbの両方を処理していることを認識しているためです。選択性が十分に高くない場合、それはまだ使用されないことがあります。

はあり

2. [SELECT * FROM buyers WHERE last_name=? AND first_name=? AND zip=?] 
can't use the index. 

は私の信じられない-FAQ-エントリは今日のために見つけるトップにいることを述べました。部分的に正しいのは、SELECT *がテーブルへのルックアップを必要とし、複合インデックスからの利益が半減(またはさらに最小化)されるためです。

explain 
SELECT first_name,last_name,zip FROM buyers WHERE first_name='Tariq' AND last_name='Iqbal' AND zip=92082; 

そしてその後、この

explain 
SELECT last_name,first_name,zip FROM buyers WHERE last_name='Iqbal' AND first_name='Tariq' AND zip=92082; 

彼らは同じプランが表示されます別のクエリでは、このコードの末尾に代わり

CREATE TABLE buyers(
buyer_id INT NOT NULL AUTO_INCREMENT, 
first_name CHAR(19) NOT NULL, 
last_name CHAR(19) NOT NULL, 
zip CHAR(5) NOT NULL, 
state_code CHAR(2) NOT NULL, 
PRIMARY KEY (buyer_id) 
); 

insert buyers values 
(991,'zeshan ','Nadeem ',92082,'CA'), 
(992,'Ken ','Marcus ',92082,'CA'), 
(993,'Tariq ','Iqbal ',92082,'CA'), 
(994,'Tariq ','Iqbal ',92082,'CA'), 
(995,'Hasnat ','Ahmad ',92083,'NY'), 
(996,'Tariq ','Iqbal ',92082,'DC'), 
(997,'Keith ','Worlf ',93083,'NG'), 
(998,'Ashley ','Lewis ',92088,'NJ'), 
(999,'Tariq ','Mehmood ',99088,'TX'); 

ALTER TABLE buyers ADD INDEX idx_firstname (first_name); 
ALTER TABLE buyers ADD INDEX idx_last_name (last_name); 
ALTER TABLE buyers ADD INDEX idx_zip (zip); 
ALTER TABLE buyers ADD INDEX idx_flname_zip(first_name,last_name,zip); 

実行これを2つのクエリを比較