[英]Optimization of an SQL Query on multiple tables with Left joins
我創建了一個自定義的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
每個用戶在這段時間內有多少個呼叫/電子郵件/任務? 該查詢實際上是對結果進行交叉聯接,因此,如果每個用戶每個有100個(例如)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的檢查不是嚴格必需的,但是可以加快速度。
我看到您正在加入表格並隨后進行過濾。 例如:
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
這樣,您將大大減少連接表所花費的時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.