为什么MySQL Innodb;“创建排序索引”;唯一索引何时存在?

为什么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将需要访问基础

在一个简单但非常大的Innodb表上,我在列a上有一个唯一的索引,我想得到一个(整数)列B的列表,按(整数)列a的顺序排列

非常简单的查询,我正在翻阅数百万条记录

从大额订单中选择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