У меня проблема с производительностью относительно простого запроса, который выполняется более 30 минут:
SELECT P.pID
,COUNT(T1.ID) AS NB1
,COUNT(T2.ID) AS NB2
,COUNT(T3.ID) AS NB3
,COUNT(T4.ID) AS NB4
,COUNT(T5.ID) AS NB5
FROM MainTable P
LEFT OUTER JOIN Table1 T1 ON P.pID = T1.pID
LEFT OUTER JOIN Table2 T2 ON P.pID = T2.pID
LEFT OUTER JOIN Table3 T3 ON P.pID = T3.pID
LEFT OUTER JOIN Table4 T4 ON P.pID = T4.pID
LEFT OUTER JOIN Table5 T5 ON P.pID = T5.pID
GROUP BY P.pID
Где каждый запрос будет отвечать за несколько мс:
отл.
SELECT P.pID
,COUNT(T1.ID) AS NB1
FROM MainTable P
LEFT OUTER JOIN Table1 T1 ON P.pID = T1.pID
GROUP BY P.pID
Если я не использую агрегацию (COUNT или что-то еще), запрос выполняется за несколько мс:
ех.
ВЫБЕРИТЕ P.pID
FROM MainTable P
LEFT OUTER JOIN Table1 T1 ON P.pID = T1.pID
LEFT OUTER JOIN Table2 T2 ON P.pID = T2.pID
LEFT OUTER JOIN Table3 T3 ON P.pID = T3.pID
LEFT OUTER JOIN Table4 T4 ON P.pID = T4.pID
LEFT OUTER JOIN Table5 T5 ON P.pID = T5.pID
GROUP BY P.pID
Очевидно, что все индексы установлены и т. Д.
Единственный элемент «замедления» - это то, что pID - это varchar (50), но я не могу его изменить, и, на мой взгляд, это не главная проблема.
Я использовал обходной путь, включая union all, который прекрасно работает, но мне действительно интересно, почему они такие длинные и как я могу оптимизировать их, так как агрегация по нескольким левым соединениям - действительно распространенная вещь в проекте отчетов и не должна быть такой медленной.
спасибо за вашу помощь.
[EDIT]
спасибо ARION Я получил хороший запрос, работающий действительно хорошо.
Но моя главная задача - понять, что не так в ядре sql, пишущем запрос с несколькими левыми соединениями.
Таблицы descr будут:
Table P (500 rows)
pID varchar(50) NOT NULL as primary key
p.* doesn't matter
Table Tn (between 2000 and 8000 rows)
Tn.ID int NOT NULL as primary key
pID varchar(50) NOT NULL as Foreign key
[РЕДАКТИРОВАТЬ] Благодаря Erland Sommarskog на social.msdn.microsoft.com, которые указывают мне мою ошибку анализа.
- подробно об ответе
Имейте в виду:
LEFT JOIN формирует декартово произведение
Я ошибался, предполагая, что декартово произведение могло быть отфильтровано, поскольку я всегда ссылаюсь на одну и ту же таблицу.
спасибо