多列索引和SQL查询的顺序

时间:2011-02-02 19:35:27

标签: sql mysql postgresql indexing

我发现了两个关于MySQL中多列索引顺序的相反陈述。 这篇文章here在评论中指出(a,b)索引也将用于(b = value1 AND a = value2)的查询。此FAQ条目here表示(在底部)完全相反(不会使用索引)。什么是正确的?那么PostgreSQL怎么样?它的行为方式是否相同?

1 个答案:

答案 0 :(得分:2)

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

并且(a,b)复合索引的索引将用于满足查询(b = value1和a = value2)。请注意,在WHERE子句中“a”之前显示“b”,因为查询引擎知道您正在处理a和b。如果选择性不够高,可能不会使用它。

说完了

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;

他们将展示相同的计划