为什么MySQL Innodb;“创建排序索引”;唯一索引何时存在?
在一个简单但非常大的Innodb表上,我在列a上有一个唯一的索引,我想得到一个(整数)列B的列表,按(整数)列a的顺序排列 非常简单的查询,我正在翻阅数百万条记录为什么MySQL Innodb;“创建排序索引”;唯一索引何时存在?,mysql,sql-order-by,innodb,filesort,Mysql,Sql Order By,Innodb,Filesort,在一个简单但非常大的Innodb表上,我在列a上有一个唯一的索引,我想得到一个(整数)列B的列表,按(整数)列a的顺序排列 非常简单的查询,我正在翻阅数百万条记录 从大额订单中选择B,以10000个偏移量500000为限 在速度非常快的服务器上,每次查询需要10秒 Filesort:Yes Filesort\u在磁盘上:Yes Merge\u通过:9 这对我来说毫无意义,为什么它不能使用索引A Explain显示简单的、不可能的键和文件排序。如果索引页中没有列B的值,那么MySQL将需要访问基础
从大额订单中选择B,以10000个偏移量500000为限
在速度非常快的服务器上,每次查询需要10秒
Filesort:Yes Filesort\u在磁盘上:Yes Merge\u通过:9
这对我来说毫无意义,为什么它不能使用索引A
Explain显示简单的、不可能的键和文件排序。如果索引页中没有列B的值,那么MySQL将需要访问基础表中的页。此外,也没有筛选正在考虑哪些行的谓词,这意味着MySQL看到所有行都需要返回。这可以解释为什么没有使用索引 还要注意,
LIMIT
操作在语句末尾处理,几乎是执行计划中的最后一步,但有一些例外
我怀疑您的查询可能会使用覆盖索引,例如“ON hugetable(a,B)
”,以避免排序操作
在没有覆盖索引的情况下,您可以尝试重写如下查询,以查看这是否会利用列a上的索引,并避免对数百万行执行排序操作(以获得按顺序返回的前510000行):
我建议您只对内联视图查询(别名为k)进行解释,看看它是否显示“使用索引”
外部查询可能仍然有一个“Using filesort
”操作,但至少只有10000行
(注意:您可能需要尝试在外部查询中使用“orderbyi.A
”代替“k.A
”,看看这是否有区别。)
附录
没有明确地回答你的问题,但是就这个查询的性能而言,如果这是“遍历”一组行,那么另一个要考虑的选项是“下一个”页,它使用从前面查询中检索到的最后一行作为“下一行的起点”的“<代码> A <代码> >。
原始查询看起来像是在“第51页”(每页10000行,第51页将是510001到520000行)
如果还要返回“A”的值,并将其保留到最后一行。要获取“下一页”,查询实际上可以是:
SELECT i.B, k.A
FROM ( SELECT j.A
FROM hugeTable j
WHERE j.A > $value_of_A_from_row_520000
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ORDER BY j.A ASC
LIMIT 10000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A
如果还保留了“第一”行中的值,则可以使用该值备份页面。这实际上只适用于向前一页或向后一页。跳转到另一个页面时,必须使用原始形式的查询,计算行数
SELECT i.B, k.A
FROM ( SELECT j.A
FROM hugeTable j
WHERE j.A > $value_of_A_from_row_520000
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ORDER BY j.A ASC
LIMIT 10000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A