为啥我在这个非常简单的 MySQL 查询上得到文件排序?

Posted

技术标签:

【中文标题】为啥我在这个非常简单的 MySQL 查询上得到文件排序?【英文标题】:Why am I getting filesort on this really simple MySQL query?为什么我在这个非常简单的 MySQL 查询上得到文件排序? 【发布时间】:2009-07-08 12:20:03 【问题描述】:

表格有两列:

CREATE TABLE items ( 
    k INT auto_increment PRIMARY KEY, 
    val INT UNSIGNED
) ENGINE=MyISAM;

我在表格中放了四项:

INSERT INTO items (val) VALUES (12),(23),(45),(56);

现在如果我这样做:

EXPLAIN SELECT * FROM items ORDER BY k;

我得到了可怕的“使用文件排序”。这是怎么回事?根据this page,它应该使用索引进行排序。我做错了吗?

在 XP 上的 mysql 5.0.41 和 ubuntu 上的 5.0.67 上测试。

更新:我向表中添加了 1,110,000 行,我添加了一个 VARCHAR 列并用文本填充它。表大小现在为 135MB,我仍在“使用文件排序”。

    有人对如何快速添加大量行有任何提示吗? 在什么时候我应该考虑一个“足够大”的表来进行查询优化测试?

【问题讨论】:

【参考方案1】:

好吧,也许,只是也许,它足够聪明,可以计算出整个表可以放在一个块中,并且不需要读取索引。将整个表读入内存并对其进行排序可能会更快(如果这甚至是必要的 - 很有可能它已经在块中按键排序)。

用更大的桌子试试。

【讨论】:

尝试了 100,000 行,结果相同。致力于创建更多行。【参考方案2】:

你可以使用:

EXPLAIN SELECT k, val FROM items FORCE INDEX(PRIMARY) ORDER BY k

我认为这可能是与索引大小等有关的 MyISAM 问题。

如果您创建与 InnoDB 相同的表并运行原始顺序,则使用 PRIMARY 索引可以正常工作。

【讨论】:

好!我遇到了完全相同的问题,FORCE INDEX 解决了它。 哦,FORCE INDEX(i) 好记;谢谢。 (这是否会强制使用索引,即使给定更大的输入集,执行计划从未使用过它?)尽管您通常应该能够信任 DBMS 提出的执行计划为自己。毕竟,它知道得更好!

以上是关于为啥我在这个非常简单的 MySQL 查询上得到文件排序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在使用 Nginx 和 Gunicorn 的 Django 应用程序上得到 502 Bad Gateway?

为啥我在一个 webpack 项目上得到“意外的令牌导入”,而在另一个项目上却没有?

为啥我在比较我的优先级队列堆中的两个索引的行上得到空值?

为啥这个 mySQL 查询非常慢?

为啥我在字符串变量上得到“程序接收信号:”EXC_BAD_ACCESS“

为啥我在使用 SOAP 的贝宝批量付款上得到 transaction_status = "Failed"?