【问题标题】:How can I optimize this query with 5 subqueries?如何使用 5 个子查询优化此查询?
【发布时间】:2014-11-20 19:09:40
【问题描述】:
SELECT
  (SELECT COALESCE(SUM(t.hours), 0) AS allotted_hours
   FROM tasks AS t
   WHERE t.projects_id = 8
     AND t.complete != 100
     AND t.name LIKE '%Ongoing%'
     AND t.name NOT LIKE '%Placeholder%') AS allotted_hours_notcomplete_ongoing,

  (SELECT COALESCE(SUM(tl.hours), 0) AS hr
   FROM tasks AS t
   INNER JOIN tasklogs AS tl ON (tl.tasks_id = t.id)
   WHERE t.projects_id = 8
     AND t.complete != 100
     AND t.name LIKE '%Ongoing%'
     AND t.name NOT LIKE '%Placeholder%') AS logged_hours_notcomplete_ongoing,

  (SELECT (allotted_hours_notcomplete_ongoing - logged_hours_notcomplete_ongoing) + logged_hours_notcomplete_ongoing) AS difference_notcomplete_ongoing,

  (SELECT COALESCE(SUM(t.hours), 0) AS hr
   FROM tasks AS t
   WHERE t.projects_id = 8
     AND t.complete != 100
     AND t.name NOT LIKE '%Ongoing%'
     AND t.name NOT LIKE 'Placeholder%') AS allotted_hours_notcomplete_regular,

  (SELECT COALESCE(SUM(tl.hours), 0) AS hr
   FROM tasklogs AS tl
   INNER JOIN tasks AS t ON (t.id = tl.tasks_id
                             AND t.projects_id = 8
                             AND t.complete = 100)
   WHERE hourtypes_id IN (1,
                          2)) AS logged_hours_complete,

  (SELECT logged_hours_complete + allotted_hours_notcomplete_regular + difference_notcomplete_ongoing) AS total

我基本上是在尝试优化此查询,以便在将其合并到我的基本 SELECT * FROM projects 查询之前计算给定项目的任务小时数。

这些子查询中的 1 个仅从 tasks 表中选择,其中 2 个从 taskstasklogs 上的 INNER JOIN 中选择,反之亦然,其中 2 个是相互简单的计算。

有没有更有效的优化方法?我从来没有使用过临时表,但也许我可以先从 tasks 中选择具有给定项目 ID 的所有任务,然后从该临时表中执行我以后的 SELECT 操作?不胜感激。

如果需要,我可以使用 sql fiddle 复制架构,但这需要一些时间。

【问题讨论】:

    标签: mysql optimization


    【解决方案1】:

    您不止一次从同一张桌子经过。如果没有任何执行计划,我会先尝试以下操作。

        SELECT 
        (SELECT SUM(GT.tHours) FROM GT
        WHERE 1 = 1
        AND t.name LIKE '%Ongoing%'
         AND t.name NOT LIKE '%Placeholder%'
        ) AS allotted_hours_notcomplete_ongoing
        , 
        (SELECT SUM(GT.tlHours) FROM GT
        WHERE 1 = 1
        AND t.name LIKE '%Ongoing%'
         AND t.name NOT LIKE '%Placeholder%'
        ) AS logged_hours_notcomplete_ongoing
        (SELECT SUM(GT.tlHours) FROM GT
        WHERE 1 = 1
        AND t.name LIKE '%Ongoing%'
         AND t.name NOT LIKE '%Placeholder%'
         AND hourtypes_id IN (1,
                              2)) 
    
        ) AS  logged_hours_complete,
        (SELECT (allotted_hours_notcomplete_ongoing - logged_hours_notcomplete_ongoing) + logged_hours_notcomplete_ongoing) AS difference_notcomplete_ongoing,
    
        (SELECT COALESCE(SUM(thours), 0) AS hr
        FROM GT
        WHERE
         AND t.name NOT LIKE '%Ongoing%'
         AND t.name NOT LIKE 'Placeholder%') AS allotted_hours_notcomplete_regular,
    
    
        FROM
        (
        SELECT SUM(t.hours) AS tHours ,SUM(tl.hours) AS tlHours, t.name,hourtypes_id
        FROM tasks AS t
        LEFT JOIN tasklogs AS tl ON (tl.tasks_id = t.id)
        WHERE t.projects_id = 8
        AND t.complete != 100
        GROUP BY t.name,hourtypes_id
        ) GT
    

    我基本上只尝试了一次总和时间。之后,我将使用内部选择和位置进行过滤。您当然需要以下索引。

    任务

    t.id
    t.projects_id
    t.complete
    t.name
    hourtypes_id
    t.hours
    

    任务日志

    tl.tasks_id
    tl.hours
    

    我假设 hourtypes_id 在任务表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-01
      • 2023-04-02
      相关资源
      最近更新 更多