2009-04-07 10 views
1

Nous avons une instruction transact sql qui interroge 4 tables avec des millions de lignes dans chacune.Requête Sql avec des jointures entre quatre tables avec des millions de lignes

Cela prend plusieurs minutes, même si elle a été optimisée avec des index et des statistiques selon TuningAdvisor.

La structure de la requête est comme:

 
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 

Étant donné que chaque table de transactions contient des millions de lignes, je considère découper en une seule requête par table de transactions, en utilisant les variables de table comme @real, @budget et @hours , puis en les joignant dans un final SELECT. Mais dans les tests, il semble ne pas accélérer.

Comment vous y prendre pour l'accélérer?

Répondre

8

Je ne suis pas sûr que la requête que vous avez publiée produira les résultats que vous attendez.

Il va croiser rejoindre toutes les tables de dimension (MoneyTransactions etc.) et multiplier tous les résultats.

Essayez ceci:

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 
+0

Hmmm ... N'est-ce pas SELECT EmployeeID, EmployeeName, SUM (...), SUM (...) FROM Employés GROUP BY EmployeeID, EmployeeName? – Tomalak

+0

Pourquoi grouper sur la clé primaire? – Quassnoi

+0

C'est une erreur (lecture bâclée). Peu importe, mon mal. +1 – Tomalak

1

Je ne sais pas si vous avez tous les index sur vos tables qui accéléreront les choses, mais ayant de grandes tables pourrait avoir cet impact sur un temps de requête. Je recommanderais de partitionner les tables si possible. C'est plus de travail, mais tout ce que vous faites pour accélérer la requête ne sera plus suffisant après quelques millions de nouveaux enregistrements.

Questions connexes