在 SO,最近有人问为什么 ORDER BY 不使用索引?
这种情况涉及 MySQL 中的一个简单的 InnoDB 表,包括三列和 10k 行。其中一列,一个整数,被索引——OP 试图检索他在该列上排序的整个表:
SELECT * FROM person ORDER BY age
Run Code Online (Sandbox Code Playgroud)
他附上了EXPLAIN
输出,显示这个查询是用 a filesort
(而不是索引)解决的,并询问为什么会这样。
尽管提示 FORCE INDEX FOR ORDER BY (age)
导致使用索引,但有人回答(通过其他人的支持评论/赞成)索引仅用于在所选列都从索引中读取时进行排序(即通常Using index
在Extra
列中指示的EXPLAIN
输出)。后来给出了一个解释,遍历索引然后从表中获取列会导致随机 I/O,MySQL 认为这比filesort
.
这似乎与关于ORDER BY
优化的手册章节背道而驰,它不仅传达了强烈的印象,即满足ORDER BY
索引比执行额外排序更可取(实际上,filesort
是快速排序和归并排序的组合,因此 必须有一个下限; 虽然按顺序遍历索引并寻找表应该是 - 所以这是完全有道理的),但它也忽略了这种所谓的“优化”,同时还说明了:Ω(nlog n)
O(n)
以下查询使用索引来解析
ORDER …
无论使用的实际 SQL 数据库系统如何,是否有统一的方法来检查给定列的 INDEX 是否存在?
例如,对于 MySQL,可以使用SHOW CREATE TABLE mytable
. 如果列mycolumn
有一个索引,结果会是这样的:KEY 'Index_1' ('mycolumn')
。
这个指标KEY
是所有SQL数据库系统统一的吗?
有没有更好的方法来检查索引?
我在 PostGreSql 数据库中有一个表定义如下:
CREATE TABLE public."MATCH"(
"ITEM_A_ID" bigint DEFAULT 0,
"ITEM_B_ID" bigint DEFAULT 0,
"OWNER_A_ID" bigint DEFAULT 0,
"OWNER_B_ID" bigint DEFAULT 0,
"OTHER_DATA" varchar(100) NOT NULL DEFAULT ''
CONSTRAINT "MATCH_PK" PRIMARY KEY ("ITEM_A_ID","ITEM_B_ID")
);
Run Code Online (Sandbox Code Playgroud)
它将包含很多行。将会对该表执行很多类似以下的查询:
SELECT * FROM "MATCH" WHERE "OWNER_A_ID" = owner_a_id;
SELECT * FROM "MATCH" WHERE "OWNER_B_ID" = owner_b_id;
Run Code Online (Sandbox Code Playgroud)
我正在考虑在OWNER_A_ID
和上创建索引OWNER_B_ID
,因为这些列不是键。这是一个好主意吗?如果是,我应该如何创建它们?我应该为两列创建一个索引吗?我应该创建两个索引吗?我应该包括其他列吗?