2011-02-02 4 views
1

Я нашел два противоположных утверждения относительно порядка индексов нескольких столбцов в MySQL. Это сообщение here имеет в комментариях, что индекс (a, b) также будет использоваться для запроса с (b = value1 AND a = value2). В этом разделе часто задаваемых вопросов here указано (внизу) точно противоположное (индекс не будет использоваться). Что правильно? А как насчет PostgreSQL? Это ведет себя так же?Порядок индексирования нескольких столбцов и SQL-запрос

+1

Я не эксперт по mySQL (только SQL Server и немного Oracle), но ответы на часто задаваемые вопросы выглядят * очень ловкими для меня (полное сканирование таблицы * три раза) из-за трех условий в ГДЕ? Puuhlease!). Каждая достойная система SQL будет использовать составной индекс для такого типа запросов (за исключением случаев, когда таблица настолько мала, что она вообще не платит за использование индекса) – TToni

ответ

2

Прежде всего позвольте мне сказать, что нет ответа на серебряную пулю.

И индексный (a, b) составной индекс будет использоваться для удовлетворения запроса (b = значение1 и a = значение2). Обратите внимание, что не имеет значение «b», представленное перед «a» в предложении WHERE, поскольку механизм запросов знает, что вы имеете дело как с a, так и с b. STILL не может использоваться, если селективность недостаточно высока.

Сказав, что

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

То есть к началу моей невероятно-чаво-записи найти на сегодняшний день. Это частично правильно, и только потому, что SELECT * требует поиска назад к таблице, поэтому любая польза от составного индекса уменьшается вдвое (или далее минимизируется). Сравните два запроса в конце этого кода вместо

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); 

Выполнить это в отдельном запросе

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; 

Они покажут тот же план

Смежные вопросы