使用 VIEW 和 LEFT OUTER JOIN 进行慢查询
Posted
技术标签:
【中文标题】使用 VIEW 和 LEFT OUTER JOIN 进行慢查询【英文标题】:Slow query with VIEW and LEFT OUTER JOIN 【发布时间】:2020-05-19 14:10:53 【问题描述】:我正在尝试以图表形式获取 30 天的交易总额视图。目前使用 VIEW 日期和 LEFT OUTER JOIN 来获取数据。这有效,显示了我所有交易的总和,并且仍然包括没有交易的天数为 0,等等。
问题是事务表非常大。所以 LEFT OUTER JOIN 做了很多工作......而且速度很慢。这是原始查询:
SELECT IFNULL(SUM(Total), 0) AS OrderTotal, MONTH(dates.date) AS Month, YEAR(dates.date) AS Year, DAY(dates.date) AS Day
FROM dates LEFT OUTER JOIN tblTransactions
ON DATE(tblTransactions.TransDate) = dates.date
WHERE dates.date > DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DAY(dates.date), MONTH(dates.date)
ORDER BY dates.date
LIMIT 30
为了加快速度,我认为最好添加一个额外的 WHERE 条件并且只查看超过 30 天的交易。这令人难以置信地加快了速度,并以为我拨了它,但问题是只有在我有 30 天的交易时才好。如果一天是 0 美元,它将返回 29 条具有此条件的记录。不好。
SELECT IFNULL(SUM(Total), 0) AS OrderTotal, MONTH(dates.date) AS Month, YEAR(dates.date) AS Year, DAY(dates.date) AS Day
FROM dates LEFT OUTER JOIN tblTransactions
ON DATE(tblTransactions.TransDate) = dates.date
WHERE dates.date > DATE_SUB(NOW(), INTERVAL 30 DAY)
AND tblTransactions.TransDate > DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DAY(dates.date), MONTH(dates.date)
ORDER BY dates.date
LIMIT 30
因此希望得到一些反馈来改进原始查询。现在,我感觉 php for() 循环 - 循环 30 次和查询 30 次可能比我原来的 LEFT OUTER JOIN 单个查询要快。
【问题讨论】:
除了尝试 Gordon Linoff 的答案,尝试将 DATE_SUB(NOW(), INTERVAL 30 DAY) 的值设置为变量并在查询中使用 【参考方案1】:left join
中第二个表的过滤需要进入on
子句:
SELECT COALESCE(SUM(t.Total), 0) AS OrderTotal,
MONTH(d.date) AS Month, YEAR(dates.date) AS Year, DAY(d.date) AS Day
FROM dates d LEFT OUTER JOIN
tblTransactions t
ON DATE(t.TransDate) = d.date AND
t.TransDate > DATE_SUB(NOW(), INTERVAL 30 DAY)
WHERE d.date > DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY DAY(d.date), MONTH(d.date)
ORDER BY d.date
LIMIT 30;
注意:导致性能不佳的原因可能是此子句:
DATE(t.TransDate) = d.date
如果TransDate
没有时间分量,那么这不是必需的。如果此类查询的性能很重要,请仅为 TransDate
的日期组件添加计算列,并在该列上添加索引。
【讨论】:
谢谢。效果很好。我还创建了一个只有日期的新字段并为其编制了索引。速度很快。以上是关于使用 VIEW 和 LEFT OUTER JOIN 进行慢查询的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 数据库中 left outer join 和 left join 啥区别
MySQL 数据库中 left outer join 和 left join 啥区别?
SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN
SQLite3 使用 LEFT JOIN 和 UNION 模拟 RIGHT OUTER JOIN