加速超时的 MySQL 查询

Posted

技术标签:

【中文标题】加速超时的 MySQL 查询【英文标题】:Speed up a MySQL query that times out 【发布时间】:2017-10-16 19:05:58 【问题描述】:

我正在尝试从需要合并在一起以进行报告的多个表中获取数据。我正在尝试获取在某个日期之后完成的每个标题的所有详细信息,并且由于数据错误而必须检查 0 日期。

我正在处理我没有创建且无法更改的旧表。此语句在我的应用程序中超时,并且需要大约 40 秒才能针对本地虚拟机上的数据库运行。是否可以重构查询以获得更好的性能?任何帮助表示赞赏!

SELECT detail.* 
FROM detail 
JOIN header 
  ON detail.invoice = header.invoice 
WHERE detail.dateapply != '0000-00-00' 
  AND header.dateapply >= '2017-09-17' 
  AND header.orderstatus IN ('complete', 'backorder') 
ORDER BY detail.DateApply;`

【问题讨论】:

dateapply是什么字段类型? 你有关于 dateapply 和 orderstatus 的索引吗? 明智的做法是为要连接和过滤的表添加适当的索引。但是既然你不能改变桌子......我猜你不走运?除非添加索引不算“不能改变” SELECT detail.* FROM detail JOIN (SELECT * FROM header WHERE header.dateapply >= '2017-09-17' AND header.orderstatus IN ('complete', 'backorder')) AS h WHERE ON detail.invoice = h.invoice WHERE detail.dateapply != '0000-00-00' AND ORDER BY detail.DateApply; 尝试减少扫描行数,如果错过则创建索引 在询问有关查询优化的问题时,您应该始终为查询中引用的每个表发布SHOW CREATE TABLE,并为查询发布当前EXPLAIN。帮助我们帮助您! 【参考方案1】:

对于header

INDEX(orderstatus, dateapply)
INDEX(invoice, orderstatus, dateapply)

对于detail

INDEX(invoice, dateapply)
INDEX(dateapply, invoice)

列的顺序是经过深思熟虑的。由于我不知道优化器将从哪个表开始,所以我提供了无论哪种方式都应该是最佳的索引。

如果两个dateapply 列是同步的,那么可能还有进一步的优化。

【讨论】:

【参考方案2】:

在我的同事和我自己之间,我们提出了以下查询,它可以更快地返回结果。 GROUP BY 消除了重复记录。在此感谢大家抽出宝贵时间帮助我看待我的问题,并期待未来使用索引的可能性。

SELECT d.* 
FROM detail d 
JOIN header h 
   ON d.invoice = h.invoice 
WHERE d.qbposted = 0 
   AND d.dateapply != '0000-00-00' 
   AND h.dateapply >= '2017-09-17' 
   AND h.orderstatus IN ('complete', 'backorder') 
GROUP BY d.rec ORDER BY d.dateapply;

【讨论】:

以上是关于加速超时的 MySQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql SELECT LEFT JOIN ON 查询总是超时,大侠能帮忙优化一下吗?

如何为 mysql 设置 ActiveRecord 查询超时?

MySQL - 加速查询避免文件排序和临时

调用某些查询时,MySQL“超过锁定等待超时”

MySQL中2种方法限制查询超时时间

使用MySQL Workbench查询超时的错误