У меня есть SQL-запрос с внутренними объединениями четырех таблиц, который занимает более 30 секунд с текущими индексами и структурой запроса. Я хотел бы сделать это как можно быстрее; как минимум быстрее 5 секунд.
Сначала я подумал о денормализации, но прочитал здесь , что, как правило, должна быть возможность оптимизации с помощью правильных индексов и т. Д. Я не могу понять это в этом случае. Текущий план запроса содержит сканирование индекса для самой маленькой таблицы и предупреждение «Нет предиката соединения» для одного из внутренних объединений.
- Как я могу оптимизировать скорость следующего?
- Какие показатели?
- Какая структура запроса?
- Другие соображения?
У нас есть следующие таблицы (с указанием количества строк и соответствующих полей):
TableName Rows Fields
------------------- ----- ----------------------------------------------
ProjectType 150 ProjectTypeID, ProjectTypeName
Employee 200 EmployeeID, RefDepartmentID
Project 0.2M ProjectID, RefProjectTypeID
ProjectTransaction 3.5M Hours, RefEmployeeID, RefProjectID, Date, Type
Запрос должен суммировать часы для данного отдела, диапазона дат и т. Д. В настоящее время я пытаюсь:
SELECT E.RefDepartmentID, SUM(PTran.Hours)
FROM Employee E
JOIN ProjectTransaction PTran
ON E.EmployeeID = PTran.RefEmployeeID
JOIN Project P
ON PTran.RefProjectID = P.ProjectID
JOIN ProjectType PType
ON P.RefProjectTypeID = PType.ProjectTypeID
WHERE E.RefDepartmentID = @departmentID
AND @from <= PTran.Date AND PTran.Date <= @to
AND PTran.Type = 0
AND PType.ProjectTypeName NOT IN (N'1', N'2', N'3')
GROUP BY E.RefDepartmentID
Спасибо за все быстрые ответы. (У меня уже были индексы по «внешним ключам» и критериям в предложении WHERE
.) Я переупорядочил запрос так, чтобы сначала были две маленькие таблицы, затем средняя и последняя. И вуаля занимает около одной секунды:
SELECT E.RefDepartmentID, SUM(PTran.Hours)
FROM Employee E
JOIN ProjectType PType
ON E.RefCustomerID = PType.RefCustomerID
JOIN Project P
ON PType.ProjectTypeID = P.RefProjectTypeID
JOIN ProjectTransaction PTran
ON E.EmployeeID = PTran.RefEmployeeID
AND P.ProjectID = PTran.RefProjectID
WHERE E.RefDepartmentID = @departmentID
AND @from <= PTran.Date AND PTran.Date <= @to
AND PTran.Type = 0
AND PType.ProjectTypeName NOT IN (N'1', N'2', N'3')
GROUP BY E.RefDepartmentID