多列索引顺序与SQL查询

多列索引顺序与SQL查询,sql,mysql,postgresql,indexing,Sql,Mysql,Postgresql,Indexing,我在MySQL中发现了关于多列索引顺序的两种相反的说法。 这篇文章在评论中提到,(a,b)索引也将用于(b=value1和a=value2)的查询。此FAQ条目(在底部)的内容正好相反(不使用索引)。什么是正确的?那么PostgreSQL呢?它的行为是一样的吗?首先让我说,没有银弹答案 (a,b)复合索引上的索引将用于满足查询(b=value1和a=value2)。请注意,WHERE子句中“b”出现在“a”之前并不重要,因为查询引擎知道您同时处理a和b。如果选择性不够高,仍然可以不使用 话虽如此

我在MySQL中发现了关于多列索引顺序的两种相反的说法。
这篇文章在评论中提到,(a,b)索引也将用于(b=value1和a=value2)的查询。此FAQ条目(在底部)的内容正好相反(不使用索引)。什么是正确的?那么PostgreSQL呢?它的行为是一样的吗?

首先让我说,没有银弹答案

(a,b)复合索引上的索引将用于满足查询(b=value1和a=value2)。请注意,WHERE子句中“b”出现在“a”之前并不重要,因为查询引擎知道您同时处理a和b。如果选择性不够高,仍然可以不使用

话虽如此

2. [SELECT * FROM buyers WHERE last_name=? AND first_name=? AND zip=?]
can't use the index.
这已经超过了我今天难以置信的faq条目。这部分是正确的,只是因为
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;
他们将显示相同的计划

我不是mySQL专家(只是SQL Server和一点Oracle),但常见问题解答在我看来非常可疑(因为WHERE?Puuhlease中有三个条件,所以全表扫描三次!)。每一个像样的SQL系统都会使用复合索引进行这种查询(除非表太小,根本不需要使用索引)