[英]Unexpected performance issue with T-SQL Query
我有以下T-SQL查詢:
SELECT Wk.WeekID,
Wk.WeekStart,
SUM(CASE WHEN NOT(Task.WeekDate IS NULL) THEN 1 ELSE 0 END) AS WeekCount,
SUM(CASE WHEN NOT(Task.DayDate IS NULL) THEN 1 ELSE 0 END) AS DayCount
FROM tblPerWeek AS Wk
LEFT OUTER JOIN tblPerTask AS Task ON (Task.WeekDate = Wk.WeekStart)
OR (Task.DayDate BETWEEN Wk.WeekStart AND Wk.WeekEnd)
WHERE (Wk.WeekStart <= @DateEnd) AND (Wk.WeekEnd >= @DateStart)
GROUP BY Wk.WeekID, Wk.WeekStart
tblPerWeek
表的結構:
WeekID int
WeekStart date
WeekEnd date
tblPerTask
表的結構:
TaskID int
WeekDate date
DayDate date
基本上,查詢計算分配給周(任務WeekCount
)或特定的星期(內DayCount
)。
tblPerWeek
有大約2800條記錄, tblPerTask
有大約70000條記錄。
現在, (Task.DayDate BETWEEN Wk.WeekStart AND Wk.WeekEnd)
條件存在一些問題/故障:
有什么收獲? 關於如何使此查詢更快的任何解決方案?
通常,通過使用UNION查詢來解決使用OR的問題。 如果兩組記錄將互斥,請使用UNION ALL,這甚至更快。
SELECT Wk.WeekID,
Wk.WeekStart,
SUM(CASE WHEN NOT(Task.WeekDate IS NULL) THEN 1 ELSE 0 END) AS WeekCount,
SUM(CASE WHEN NOT(Task.DayDate IS NULL) THEN 1 ELSE 0 END) AS DayCount
FROM tblPerWeek AS Wk
LEFT OUTER JOIN tblPerTask AS Task ON Task.WeekDate = Wk.WeekStart
WHERE (Wk.WeekStart <= @DateEnd) AND (Wk.WeekEnd >= @DateStart)
GROUP BY Wk.WeekID, Wk.WeekStart
UNION
SELECT Wk.WeekID,
Wk.WeekStart,
SUM(CASE WHEN NOT(Task.WeekDate IS NULL) THEN 1 ELSE 0 END) AS WeekCount,
SUM(CASE WHEN NOT(Task.DayDate IS NULL) THEN 1 ELSE 0 END) AS DayCount
FROM tblPerWeek AS Wk
LEFT OUTER JOIN tblPerTask AS Task ON Task.DayDate BETWEEN Wk.WeekStart AND Wk.WeekEnd
WHERE (Wk.WeekStart <= @DateEnd) AND (Wk.WeekEnd >= @DateStart)
GROUP BY Wk.WeekID, Wk.WeekStart
優化器討厭OR
SELECT Wk.WeekID,
Wk.WeekStart,
SUM(CASE WHEN TaskW.WeekDate IS NULL THEN 0 ELSE 1 END) AS WeekCount,
SUM(CASE WHEN TaskD.DayDate IS NULL THEN 0 ELSE 1 END) AS DayCount
FROM tblPerWeek AS Wk
LEFT OUTER JOIN tblPerTask AS TaskW ON TaskW.WeekDate = Wk.WeekStart
LEFT OUTER JOIN tblPerTask AS TaskD ON TaskD.DayDate BETWEEN Wk.WeekStart AND Wk.WeekEnd
WHERE Wk.WeekStart <= @DateEnd AND Wk.WeekEnd >= @DateStart
GROUP BY Wk.WeekID, Wk.WeekStart
我想你可以做一個計數,因為null為零
SELECT Wk.WeekID, Wk.WeekStart,
COUNT(TaskW.WeekDate) AS WeekCount,
COUNT(TaskD.DayDate) AS DayCount
FROM tblPerWeek AS Wk
LEFT OUTER JOIN tblPerTask AS TaskW ON TaskW.WeekDate = Wk.WeekStart
LEFT OUTER JOIN tblPerTask AS TaskD ON TaskD.DayDate BETWEEN Wk.WeekStart AND Wk.WeekEnd
WHERE Wk.WeekStart <= @DateEnd AND Wk.WeekEnd >= @DateStart
GROUP BY Wk.WeekID, Wk.WeekStart
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.