Порядок многостолбцовых индексов и SQL-запросов - PullRequest
1 голос
/ 02 февраля 2011

Я нашел два противоположных утверждения относительно порядка многостолбцовых индексов в MySQL.Этот пост здесь содержит в комментариях, что индекс (a, b) также будет использоваться для запроса с (b = значение1 И a = значение2).Эта запись часто задаваемых вопросов здесь говорит (снизу) с точностью до наоборот (индекс не будет использоваться).Что правильно?А как насчет PostgreSQL?Он ведет себя так же?

1 Ответ

2 голосов
/ 02 февраля 2011

Сначала позвольте мне сказать, что ответа серебряной пули нет.

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

Сказав это

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

Это должно превысить мою невероятную находку faq-entry на сегодня. Это частично верно, и только потому, что 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;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...