【问题标题】:Mysql Order BY SpeedMysql 按速度排序
【发布时间】:2020-12-13 14:52:12
【问题描述】:

有 2 个样本。

在第一个示例中,使用 orderby 时结果更快。 (根据phpmyadmin速度报告)

在另一个示例中,我不使用 order by,它会产生较慢的结果。 (根据phpmyadmin速度报告)

使用Orderby时快速出结果是不是很不合理?

排名对我来说并不重要,重要的是速度。

select bayi,tutar 
from siparisler 
where durum='1' and MONTH(tarih) = MONTH(CURDATE()) and YEAR(tarih) = YEAR(CURRENT_DATE()) 
order by id desc

速度:0.0006

select bayi,tutar
from siparisler 
where durum='1' and MONTH(tarih) = MONTH(CURDATE()) and YEAR(tarih) = YEAR(CURRENT_DATE())

速度:0.7785

【问题讨论】:

  • @Julia 按原样带来是另一回事。分类和带来是另一回事。
  • 执行计划的比较显示了什么?
  • @PM 77-1 速度已经写在上面了
  • Execution plan 将向您展示查询是如何实现的,并帮助您解释差异。
  • 查询缓存是否开启?再试一次SQL SQL_NO_CACHE ...

标签: mysql sql sql-order-by query-optimization mysql-5.7


【解决方案1】:

order by 查询的执行速度永远不会比没有 order by 子句的相同查询快。对行进行排序会为数据库带来更多工作。在最好的情况下,排序变为无操作,因为 MySQL 首先以正确的顺序获取行:但这只会使两个查询在性能方面相等(它不会使排序更快的查询)。

order by 的结果可能已经被缓存了,所以 MYSQL 直接从缓存中为您提供结果,而不是实际执行查询。

如果性能对您来说最重要,我建议更改 where 谓词以便不在 tarih 列上使用日期函数:这样的构造会阻止数据库利用索引(我们说谓词是非 SARGable 的)。考虑:

select bayi, tutar 
from siparisler 
where 
    durum = 1 
    and tarih >= dateformat(current_date, '%Y-%m-01')
    and tarih <  dateformat(current_date, '%Y-%m-01') + interval 1 month
order by id desc

为了这个查询的性能,考虑(durum, tarih, id desc, bay, tutar) 上的索引:它应该作为一个覆盖索引,MySQL 可以使用它来执行整个查询,甚至无需查看实际数据。

【讨论】:

  • 所以这是来自缓存。结果,orderby 会减慢使用速度吗?
  • @othermember:是的 - 或者,至少,它不会加快查询速度,正如我的回答中所解释的那样。
  • 那么如何在mysql的任意表中定义默认的“order by id desc”呢?
  • @othermember:没有像 default order by 这样的东西。另一方面,您可以创建我建议的索引:连同我的查询版本,它应该有助于 MySQL 加快速度。
  • 但是,我读过的一些资料表明,如果创建“索引”,查询会很快。这和我说的一样吗?
【解决方案2】:

在 0.0006 秒时,您几乎可以肯定测量的是 query_cache 的性能,而不是执行时间。使用 SELECT SQL_NO_CACHE 再次尝试这两个查询,看看性能差异是什么。

【讨论】:

    【解决方案3】:

    首先,我建议将查询编写为:

    select bayi, tutar 
    from siparisler p
    where durum = 1 and -- no quotes assuming this is an integer 
          tarih >= curdate() - interval (1 - day(curdate()) day;
    

    这可以利用(durm, tarih) 上的索引。

    但这不是你的问题。 order by 可能会导致完全不同的执行计划。这是假设性的,但目的是解释这种情况是如何发生的。

    让我假设以下内容:

    • 该表只有(id desc, durum, tarih) 的索引。
    • where 子句匹配几行。
    • 行很宽。

    没有order by 的查询可能会生成一个全表扫描的执行计划。因为行很宽,会读取很多不必要的数据。

    order by 的查询可以按顺序读取数据然后应用 where 条件。这会比其他版本更快,因为只会读入符合where 条件的行。

    我不能保证会发生这种情况。但是查询会出现一些违反直觉的情况。

    【讨论】:

    • 与整数列相比,整数文字周围的引号不会影响性能。
    【解决方案4】:

    可以通过EXPLAIN命令分析,然后查看type字段、index或者all对应的值

    示例:

    EXPLAIN SELECT bayi,tutar 
    FROM siparisler 
    WHERE durum='1' AND MONTH(tarih) = MONTH(CURDATE()) AND YEAR(tarih) = YEAR(CURRENT_DATE()) 
    ORDER BY id DESC;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-11
      • 1970-01-01
      • 2012-08-20
      • 1970-01-01
      • 2012-09-17
      • 2011-09-24
      • 2018-06-30
      相关资源
      最近更新 更多