我们有一个transact sql语句,用于查询4个表,每个表中包含数百万行。
虽然根据TuningAdvisor对索引和统计数据进行了优化,但需要几分钟时间。
查询的结构如下:
SELECT E.EmployeeName , SUM(M.Amount) AS TotalAmount , SUM(B.Amount) AS BudgetAmount , SUM(T.Hours) AS TotalHours , SUM(TB.Hours) AS BudgetHours , SUM(CASE WHEN T.Type = 'Waste' THEN T.Hours ELSE 0 END) AS WastedHours FROM Employees E LEFT JOIN MoneyTransactions M ON E.EmployeeID = M.EmployeeID LEFT JOIN BudgetTransactions B ON E.EmployeeID = B.EmployeeID LEFT JOIN TimeTransactions T ON E.EmployeeID = T.EmployeeID LEFT JOIN TimeBudgetTransactions TB ON E.EmployeeID = TB.EmployeeID GROUP BY E.EmployeeName
由于每个事务表包含数百万行,我考虑使用@real
,@budget
和@hours
等表变量将每个事务表拆分为一个查询,然后加入最后SELECT
中的这些。但在测试中它似乎没有加速。
为了加快速度,你会如何应对?
答案 0 :(得分:8)
我不确定您发布的查询是否会产生您期望的结果。
它将交叉连接所有维度表(MoneyTransactions等)并将所有结果相乘。
试试这个:
SELECT E.EmployeeName,
(
SELECT SUM(amount)
FROM MoneyTransactions m
WHERE M.EmployeeID = E.EmployeeID
) AS TotalAmount,
(
SELECT SUM(amount)
FROM BudgetTransactions m
WHERE M.EmployeeID = E.EmployeeID
) AS BudgetAmount,
(
SELECT SUM(hours)
FROM TimeTransactions m
WHERE M.EmployeeID = E.EmployeeID
) AS TotalHours,
(
SELECT SUM(hours)
FROM TimeBudgetTransactions m
WHERE M.EmployeeID = E.EmployeeID
) AS BudgetHours
FROM Employees E
答案 1 :(得分:1)
我不知道你的表上是否有所有索引可以加快速度,但拥有大表会对查询时间产生影响。 如果可能的话,我建议对表进行分区。这是更多的工作,但是你现在所做的一切都是为了加快查询速度,在几百万条新记录之后它还不够。
答案 2 :(得分:0)
尝试这个:
SELECT E.EmployeeName, TA.TotalAmount, BA.BudgetAmount, TWH.TotalHours, BH.BudgetHours, TWH.WastedHours
FROM Employees E
LEFT JOIN
(SELECT E.EmployeeID, SUM(M.Amount) AS TotalAmount
FROM Employees E INNER JOIN MoneyTransactions M ON E.EmployeeID = M.EmployeeID GROUP BY E.EmployeeID)TA
ON E.EmployeeID = TA.EmployeeID
LEFT JOIN
(SELECT E.EmployeeID , SUM(B.Amount) AS BudgetAmount
FROM Employees E INNER JOIN BudgetTransactions B ON E.EmployeeID = B.EmployeeID GROUP BY E.EmployeeID)BA
ON E.EmployeeID = BA.EmployeeID
LEFT JOIN
(SELECT E.EmployeeID , SUM(T.Hours) AS TotalHours , SUM(CASE WHEN T.Type = 'Waste' THEN T.Hours ELSE 0 END) AS WastedHours
FROM Employees E INNER JOIN TimeTransactions T ON E.EmployeeID = T.EmployeeID GROUP BY E.EmployeeID)TWH
ON E.EmployeeID = TWH.EmployeeID
LEFT JOIN
(SELECT E.EmployeeID , SUM(TB.Hours) AS BudgetHours
FROM Employees E INNER JOIN TimeBudgetTransactions TB ON E.EmployeeID = TB.EmployeeID GROUP BY E.EmployeeID)BH
ON E.EmployeeID = BH.EmployeeID