加速超时的 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 查询总是超时,大侠能帮忙优化一下吗?