如何使用5个子查询优化此查询?

时间:2014-11-20 19:09:41

标签: mysql optimization

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个选自tasks,而tasklogs选择INNER JOIN,反之亦然,其中2个是彼此简单的计算。

是否有更有效的优化方法?我从来没有使用临时表,但也许我可以先用tasks选择具有给定项目ID的所有任务,然后从该临时表中执行后来的SELECT?非常感谢任何建议。

如果需要,我可以用sql小提琴复制模式,但这需要一些时间。

1 个答案:

答案 0 :(得分: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

tasklogs

tl.tasks_id
tl.hours

我认为hourtypes_id在任务表中。