3

我有一个包含 170,000 条记录的拥抱表。

这个查询有什么区别

Showing rows 0 - 299 (1,422 total, Query took 1.9008 sec)
    SELECT 1 FROM `p_apartmentbuy` p 
    where 
    p.price between 500000000 and 900000000
    and p.yard = 1
    and p.dateadd between 1290000000 and 1320000000
    ORDER BY `p`.`id` desc
    limit 1669

解释 在此处输入图像描述

和这个:

Showing rows 0 - 299 (1,422 total, Query took 0.2625 sec)
    SELECT 1 FROM `p_apartmentbuy` p 
    where 
    p.price between 500000000 and 900000000
    and p.yard = 1
    and p.dateadd between 1290000000 and 1320000000
    ORDER BY `p`.`id` desc
    limit 1670

解释: 在此处输入图像描述

这两个查询都使用 1 个具有相同数据的表并且具有相同的 where clasue,但只有限制行数不同

4

2 回答 2

3

MySQL 有一个用于排序的缓冲区。当要排序的东西太大时,它会对块进行排序,然后对它们进行归并排序。这称为“文件排序”。您的第 1670 行显然只是溢出了排序缓冲区。

在此处阅读更多详细信息。

现在为什么它为内存排序选择另一个键......我不太确定;但显然它的策略不是很好,因为它最终变慢了。

于 2012-04-09T16:00:17.557 回答
1

回顾:奇怪的是返回更多行的查询运行得更快

这与缓冲区与文件排序无关,对 1400 条记录进行排序只需不到 1 秒

第一个解释显示查询优化器进行线性扫描,第二个解释显示它使用索引。即使是部分有用的索引通常也比没有索引要好得多。

在内部,mysql 维护有关索引大小的统计信息,并尝试猜测哪个索引,或者线性扫描是否会更快。这个估计是特定于数据的,我已经看到 mysql 在 100 次中使用正确的索引 99 次,但时不时地选择一个不同的索引并且运行查询慢 50 倍。

您可以使用 SELECT ... FROM ... FORCE INDEX (...) 覆盖内置查询优化器并手动指定要使用的索引

于 2015-02-10T04:17:10.880 回答