【问题标题】:DATEDIFF with DATEADD causing slow performance in MySQL query带有 DATEADD 的 DATEDIFF 导致 MySQL 查询性能下降
【发布时间】:2017-03-21 04:26:49
【问题描述】:

下面的查询需要大约 2 秒,对于只有大约 3000 行左右的 2 个表进行如此简单的连接,这似乎真的很长。

我强烈怀疑问题出在这一行:

但我不知道为什么。或者,也许连接条件搞砸了?

SELECT DISTINCT
, idnum
, DATEDIFF( DATE_ADD(atable.adate, INTERVAL 10 DAY), btable.bdate) as `DIFF`
  FROM atable
LEFT JOIN btable
ON atable.idnum = btable.idnum
;

我的问题类似于this,但不一样。提前感谢伟大的 SO 社区查看此内容。

【问题讨论】:

  • 最可能的解释是没有合适的索引。 DISTINCT 关键字将强制 MySQL 执行“使用文件排序”操作来识别和删除重复项。使用 EXPLAIN 查看执行计划。并确保 btable 具有以 idnum 为前导列的索引。理想情况下,覆盖两个表的索引.... ON btable (idnum,bdate) 和 ON atable (idnum,adate)。我怀疑 DATEDIFF 和 DATE_ADD 函数的性能影响可以忽略不计。我怀疑高杆正在实现结果和“使用文件排序”操作。
  • 感谢您的帮助。解释告诉我这是一个“全部”类型的连接。你是对的——注释掉 DATEDIFF 部分并没有加快查询速度!
  • 如果没有 WHERE 子句(atable 上的任何谓词),我们希望 EXPLAIN 显示“all”...查询必须访问 atable 中的每一行。我们想知道的是外部连接到btable 的访问计划。理想情况下,使用覆盖索引,我们会在 Extra 列中看到“使用索引”。 type 列中显示的内容将取决于 btable 中 idnum 的唯一性和可空性,以及合适索引的可用性。 .
  • 请为两张表提供SHOW CREATE TABLE。
  • SELECT 中的表达式与速度的关系相对较小。所以,我声明 DATEADD 和 DATEDIFF 不是反派。

标签: mysql datediff query-performance


【解决方案1】:

您可以通过创建此查询的视图并调用该视图而不是直接查询表来减少时间。像这样

创建视图

CREATE VIEW viewname AS SELECT DISTINCT
, idnum
, DATEDIFF( DATE_ADD(atable.adate, INTERVAL 10 DAY), btable.bdate) as `DIFF`
  FROM atable
LEFT JOIN btable
ON atable.idnum = btable.idnum
;

通话视图

SELECT * FROM viewname

注意:在视图方法中,我们一次创建视图并根据需要多次调用该视图。

【讨论】:

  • 一个很好的演示创建存储视图并在查询中引用它。但这如何“减少时间”?是否有任何证据表明引用视图实际上会提高性能,即减少查询执行时间? (注:为了分析性能,我们要绕过mysql查询缓存,)
  • 从技术上讲,视图是临时表,它的作用类似于缓存,它是预先构建的数据,可以立即对请求做出反应。但在直接查询 sql 引擎中,首先创建临时数据然后响应。所以换句话说,我们通过使用视图节省了临时数据生成的时间。 :)
  • “证明”是无效的,因为它适用于 sql-server,而不是 MySQL。
  • mysql 也是基于 sql server 并使用 dbengines 处理其中发生的每一件事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
  • 1970-01-01
相关资源
最近更新 更多