我已经创建了一个自定义的mysql查询,它运行正常并显示了我想要的输出,但是由于数据量很大,它目前需要花费很多时间。
所以,请帮助我优化查询运行时间。
SELECT t.*, te + tc + tt AS total, (te + tc + tt)/7 AS weekly_Avg
FROM (SELECT t2.first_name, COUNT(DISTINCT emails.id) AS te,
COUNT(DISTINCT calls.id) AS tc, COUNT(DISTINCT tasks.id) AS tt
FROM users AS t2
LEFT JOIN emails
ON t2.id = emails.assigned_user_id
AND emails.date_entered >= '2014-03-20 00:00:00'
AND emails.date_entered <= '2014-06-30 00:00:00'
LEFT JOIN calls
ON t2.id = calls.assigned_user_id
AND calls.date_entered >= '2014-03-20 00:00:00'
AND calls.date_entered <= '2014-06-30 00:00:00'
LEFT JOIN tasks
ON t2.id = tasks.assigned_user_id
AND tasks.date_entered >= '2014-03-20 00:00:00'
AND tasks.date_entered <= '2014-06-30 00:00:00')
WHERE t2.id IN ('1', '2')
GROUP BY t2.id) t
答案 0 :(得分:1)
该时段内每位用户有多少个电话/电子邮件/任务?这个查询实际上是对结果进行交叉连接,所以如果每个用户有(比方说)100个,那么每个用户就会得到1000000条记录,然后整理出该列表中的唯一记录。
如果是这样,可能更容易使用子查询来获取每个计数并将结果连接在一起。
SELECT t . * ,te+tc+tt as total , (,te+tc+tt)/7 as weekly_Avg
FROM
(
SELECT t2.first_name, emails_count AS te, calls_count AS tc, tasks_count AS tt
FROM `users` AS t2
LEFT JOIN
(
SELECT assigned_user_id, COUNT( emails.id ) AS emails_count
FROM emails
WHERE emails.assigned_user_id IN ( '1', '2')
AND (emails.date_entered >= '2014-03-20 00:00:00'
AND emails.date_entered <= '2014-06-30 00:00:00')
GROUP BY assigned_user_id
) sub_emails
ON t2.id = sub_emails.assigned_user_id
LEFT JOIN
(
SELECT assigned_user_id, COUNT( calls.id ) AS calls_count
FROM calls
WHERE calls.assigned_user_id IN ( '1', '2')
AND (calls.date_entered >= '2014-03-20 00:00:00'
AND calls.date_entered <= '2014-06-30 00:00:00')
GROUP BY assigned_user_id
) sub_calls
ON t2.id = sub_calls.assigned_user_id
LEFT JOIN
(
SELECT assigned_user_id, COUNT( tasks.id ) AS tasks_count
FROM tasks
WHERE tasks.assigned_user_id IN ( '1', '2')
AND (tasks.date_entered >= '2014-03-20 00:00:00'
AND tasks.date_entered <= '2014-06-30 00:00:00')
GROUP BY assigned_user_id
) sub_tasks
ON t2.id = sub_tasks.assigned_user_id
WHERE t2.id IN ('1', '2')
)t
请注意,子查询中对user_id的检查不是绝对必要的,但应该加快速度。
答案 1 :(得分:0)
我看到你之后加入表格并过滤。例如:
SELECT t2.first_name, COUNT( DISTINCT emails.id ) AS te, COUNT( DISTINCT calls.id ) AS tc, COUNT( DISTINCT tasks.id ) AS tt
FROM `users` AS t2
LEFT JOIN emails ON t2.id = emails.assigned_user_id
AND (
emails.date_entered >= '2014-03-20 00:00:00'
AND emails.date_entered <= '2014-06-30 00:00:00'
)
你应该做这样的事情:
SELECT t2.first_name, COUNT( DISTINCT emails.id ) AS te, COUNT( DISTINCT calls.id ) AS tc, COUNT( DISTINCT tasks.id ) AS tt
FROM `users` AS t2
LEFT JOIN
(SELECT FIELDS_YOU_NEED
FROM `emails`
WHERE date_entered >= '2014-03-20 00:00:00' AND date_entered <= '2014-06-30 00:00:00'
) AS emails2
ON t2.id = emails2.assigned_user_id
通过这种方式,您可以显着减少加入表格所需的时间。