SQL запрос с объединением четырех таблиц с миллионами строк - PullRequest
1 голос
/ 07 апреля 2009

У нас есть транзакционный 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, а затем объединить их в окончательный * 1011. *. Но в тестах он, кажется, не ускоряется.

Как бы вы справились с этим, чтобы ускорить его?

Ответы [ 3 ]

8 голосов
/ 07 апреля 2009

Я не уверен, что отправленный вами запрос даст ожидаемые результаты.

Будет выполнено перекрестное объединение всех таблиц измерений (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 голос
/ 07 апреля 2009

Я не знаю, есть ли у вас все индексы в ваших таблицах, которые ускорят процесс, но наличие больших таблиц может повлиять на время запроса. Я бы порекомендовал разделить таблицы, если это возможно. Это больше работы, но всего, что вы делаете для ускорения запроса сейчас, этого будет недостаточно после нескольких миллионов новых записей.

0 голосов
/ 20 июля 2018

Попробуйте это:

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
...