sql - 多列索引的顺序和SQL查询

标签 sql mysql postgresql indexing

关于 MySQL 中多列索引的顺序,我发现了两个相反的说法。 本帖here在评论中有一个 (a, b) 索引也将用于带有 (b = value1 AND a = value2) 的查询。此常见问题解答条目 here说(在底部)完全相反(不会使用索引)。什么是正确的? PostgreSQL 又如何呢?它的行为是否相同?

最佳答案

首先让我说,没有 Elixir 。

并且 (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.

这必须是我今天发现的令人难以置信的常见问题条目。这是部分正确的,只是因为 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;

他们会展示相同的计划

关于sql - 多列索引的顺序和SQL查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4878975/

相关文章:

mysql - 根据 SQL 中的日期计算百分位数

c# - SQL 查询只运行一次

ruby - 最佳批量大小 PostgreSQL 更新

java - 如何将Java函数转换为postgresql函数

sql - 错误 : syntax error at or near "INSERT" , SQL 触发器,协议(protocol)表

sql - 将列中的数据替换为 SQL 中的字符

与下次运行相比,sql 查询需要很长时间

c# - 单个 ODBC ExecuteNonQuery (C#) 中的多个插入语句

mysql - 使用 AND OR 在 mysql 查询中获取正确的行

mysql - 更改Rails应用程序的MySQL表中的自增ID