【问题标题】:Sql query performance difference between limit row count限制行数之间的sql查询性能差异
【发布时间】:2012-04-09 15:55:29
【问题描述】:

我有一个包含 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,但只有限制行数不同

【问题讨论】:

    标签: mysql sql database performance


    【解决方案1】:

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

    阅读更多详情here

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

    【讨论】:

    • MySQL 中是否也有页面缓存?这在 SQL Server 中很常见,因为数据在内存中,所以第二次运行速度更快。
    • tnx 寻求答案。如何禁用此缓冲区进行排序?
    • 你可以设置@@sort_buffer_size,但这是一个hack。要尝试的一件事是SELECT ... USE INDEX(yard),以确保使用更快的策略;看看EXPLAIN 对此有何评论。
    • @Amadan: 我测试了第一个查询(2sec) SELECT ... USE INDEX(yard) ... LIMIT 1669。但是这次查询花费了 0.2 秒
    • 对不起,看来我帮不了你了…… :(
    【解决方案2】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-29
      • 2017-03-13
      • 1970-01-01
      • 2020-02-04
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 2013-04-15
      相关资源
      最近更新 更多