ck_*_*ck_ 6 mysql innodb sql-order-by filesort
在一个简单但非常大的InnoDB表,我对A列的唯一索引,我想在(整数)列A的为了得到(整数)B列的列表
非常简单的查询,我正在翻阅数百万条记录.
SELECT B FROM hugeTable ORDER BY A LIMIT 10000 OFFSET 500000
在非常快的服务器上每次查询需要10秒钟?
Filesort: Yes Filesort_on_disk: Yes Merge_passes: 9
这对我来说没有意义,为什么它不能使用索引A?
说明显示简单,没有可能的键和文件.
spe*_*593 12
如果列B的值在索引页中不可用,则MySQL将需要访问基础表中的页面.此外,没有谓词可以过滤正在考虑的行,这意味着MySQL会看到需要返回所有行.这可以解释为什么索引没有被使用.
另请注意,LIMIT操作在语句结束时处理,几乎是执行计划的最后一步,但有一些例外.
8.2.1.3.优化LIMIT查询 http://dev.mysql.com/doc/refman/5.5/en/limit-optimization.html
我怀疑你的查询可以使用覆盖索引,例如" ON hugetable (A,B)",以避免排序操作.
如果没有覆盖索引,您可以尝试重写这样的查询,看看是否会使用A列上的索引,并避免对数百万行进行排序操作(按顺序返回前510,000行):
SELECT i.B
FROM ( SELECT j.A
FROM hugeTable j
ORDER
BY j.A
LIMIT 10000 OFFSET 500000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A
Run Code Online (Sandbox Code Playgroud)
我建议你EXPLAIN只对内联视图查询(别名为k)进行操作,看看它是否显示" Using index."
外部查询可能仍然具有" Using filesort"操作,但至少只有10,000行.
(注意:你可能想在外部查询上尝试用" ORDER BY i.A"代替" k.A",看看是否有所不同.)
附录
没有专门针对您的问题,但就该查询的性能而言,如果这是"分页"一组行,另一个需要考虑的选项是,要进入"下一页",请使用" A"中的"在上一个查询中检索的最后一行作为下一行的"起始点".
原始查询看起来像是"第51页"(每页10,000行,第51页是行510,001到520,000).
如果你还要返回'A'的值,并保留最后一行.要获取"下一页",查询实际上可能是:
SELECT i.B, k.A
FROM ( SELECT j.A
FROM hugeTable j
WHERE j.A > $value_of_A_from_row_520000
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LIMIT 10000
) k
JOIN hugetable i
ON i.A = k.A
ORDER
BY k.A
Run Code Online (Sandbox Code Playgroud)
如果您还从"第一"行保留了A的值,则可以使用它来备份页面.这实际上只适用于前一页或后一页.跳转到不同的页面,将不得不使用查询的原始形式,计算行.
| 归档时间: |
|
| 查看次数: |
23405 次 |
| 最近记录: |