1
我发现了两个与MySQL中多列索引顺序相反的声明。 此帖子here在评论中指出,(a,b)索引也将用于(b = value1 AND a = value2)的查询。这个FAQ条目here说(底部)正好相反(索引不会被使用)。什么是正确的?那么PostgreSQL呢?它的行为方式是否相同?多列索引和SQL查询的顺序
我发现了两个与MySQL中多列索引顺序相反的声明。 此帖子here在评论中指出,(a,b)索引也将用于(b = value1 AND a = value2)的查询。这个FAQ条目here说(底部)正好相反(索引不会被使用)。什么是正确的?那么PostgreSQL呢?它的行为方式是否相同?多列索引和SQL查询的顺序
首先让我说,没有银弹答案。
并且将使用(a,b)复合索引上的索引来满足查询(b = value1和a = value2)。请注意它的确如此,而不是,因为查询引擎知道你正在处理a和b,因此“b”在WHERE子句中的“a”之前出现。如果选择性不够高,它仍然不能使用。
话虽如此
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),但那个FAQ的答案看起来很可怕(全表扫描*三次*次b因为在哪里有三个条件? Puuhlease!)。每一个体面的SQL系统都会使用这种查询的组合索引(除非表格太小而根本不支付索引) – TToni 2011-02-02 19:44:55