使用 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

LEFT OUTER JOIN 和 NOT EXISTS 查询

SQL中的left outer join,inner join,right outer join用法详解