【问题标题】:Slow query with VIEW and LEFT OUTER JOIN使用 VIEW 和 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) 的值设置为变量并在查询中使用

标签: php mysql sql


【解决方案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 的日期组件添加计算列,并在该列上添加索引。

【讨论】:

  • 谢谢。效果很好。我还创建了一个只有日期的新字段并为其编制了索引。速度很快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2013-03-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多