【问题标题】:Performance issue - refactor select subqueries which are doing the same joins性能问题 - 重构执行相同连接的选择子查询
【发布时间】:2020-01-28 13:36:37
【问题描述】:

在 MySQL 中,您将如何重新编写一个 SELECT 查询,其中 JOIN SELECT 子查询执行几乎相同的操作。

就我而言,我遇到了性能问题,因为在子查询中,我需要为每个子查询加入相同的表,这是一项繁重的操作。

考虑下面的(丑陋的)例子:

set @businessdate = '2020-01-24';

Select Daily.*, Monthly.Price, Yearly.Price FROM
# DAILY
(Select @businessdate as BusinessDate, t1.Owner , SUM(t.Price) AS DailyPrice
FROM Table t
INNER JOIN Table2 t2 on ...
INNER JOIN Table1 t1 on ...
where t2.date = @businessdate
GROUP BY t1.Owner) Daily

INNER JOIN
# MONTHLY
(Select SUM(t.Price) AS Price, t1.Owner
FROM Table t
INNER JOIN Table2 t2 on ...
INNER JOIN Table1 t1 on ...
where MONTH(t2.date) = MONTH(@businessdate) and YEAR(t2.date) = YEAR(@businessdate)
GROUP BY t1.Owner) Monthly

INNER JOIN
#YEARLY
(Select SUM(t.Price) AS Price, t1.Owner
FROM Table t
INNER JOIN Table2 t2 on ...
INNER JOIN Table1 t1 on ...
where YEAR(t2.date) = YEAR(@businessdate)
GROUP BY t1.Owner) Yearly

原因是我需要 where 子句中的日期(来自 t2),以及来自 t1 的组中的一个字段。我还需要显示 t1 中的一些字段。

我只需要SUM(Price)(每月和每年的价格......)所以对我来说,即使它工作正常(非常慢......)子查询中的连接听起来也有点过头了(非常慢......)

【问题讨论】:

    标签: mysql sql join


    【解决方案1】:

    您可以对单个查询使用条件聚合:

    Select
        @businessdate as BusinessDate, ... ,
        SUM(CASE WHEN t2.date = @businessdate THEN t.Price ELSE 0 END) AS DailyPrice,
        SUM(CASE WHEN MONTH(t2.date) = MONTH(@businessdate) AND
                      YEAR(t2.date) = YEAR(@businessdate)
                 THEN t.Price ELSE 0 END) AS MonthlyPrice,
        SUM(CASE WHEN YEAR(t2.date) = YEAR(@businessdate)
                 THEN t.Price ELSE 0 END) AS AnnualPrice
    FROM Table t
    INNER JOIN Table2 t2 on ...
    INNER JOIN Table1 t1 on ...
    GROUP BY t1.Owner
    

    这至少可以让您避免不必要的通过连接的表。请注意,您的 GROUP BY 子句在书面上无效;除条件总和外,营业日期是唯一可以选择的有效单列。

    【讨论】:

    • 这绝对是一个更具可读性的解决方案!谢谢您的回答。事实上,我编辑了我最初的帖子。我试图添加尽可能少的信息以使其易于理解(并且可读......)。出于某种原因,与子查询相比,您的解决方案速度较慢。我需要在我这边挖掘
    猜你喜欢
    • 1970-01-01
    • 2012-10-29
    • 1970-01-01
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多