关于运行超过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或其他任何),查询将在几毫秒内运行: 恩。 SELECT 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),但我不能改变它,在我看来这不是主要的问题。
我使用了一个解决方法,包括联合所有工作正常,但我真的想知道为什么这些很长,我怎么能优化这个,因为汇总多个左连接在报告项目中真的很常见,不应该这么慢。
谢谢你的帮助。
[编辑] thx到 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
[编辑]感谢social.msdn.microsoft.com上的 Erland Sommarskog ,指出了我的分析错误。 - 有关答案的详细信息
请记住:
LEFT JOIN形成笛卡尔积
我错了,假设笛卡尔积可能已被过滤,因为我总是引用同一张表。
感谢
答案 0 :(得分:3)
也许是这样的:
SELECT
P.pID,
(SELECT COUNT(*) FROM Table1 T1 WHERE P.pID = T1.pID) AS NB1,
(SELECT COUNT(*) FROM Table2 T2 WHERE P.pID = T2.pID) AS NB2,
(SELECT COUNT(*) FROM Table3 T3 WHERE P.pID = T3.pID) AS NB3,
(SELECT COUNT(*) FROM Table4 T4 WHERE P.pID = T4.pID) AS NB4,
(SELECT COUNT(*) FROM Table5 T5 WHERE P.pID = T5.pID) AS NB5
FROM MainTable P
答案 1 :(得分:1)
您还可以通过首先按(在子查询中)分组,然后加入:
来重写查询SELECT
P.pID,
T1.NB1,
T2.NB2,
T3.NB3,
T4.NB4,
T5.NB5
FROM MainTable P
LEFT JOIN
(SELECT pID, COUNT(*) AS NB1 FROM Table1 GROUP BY pID) AS T1
ON T1.pID = P.pID
LEFT JOIN
(SELECT pID, COUNT(*) AS NB2 FROM Table2 GROUP BY pID) AS T2
ON T2.pID = P.pID
LEFT JOIN
(SELECT pID, COUNT(*) AS NB3 FROM Table3 GROUP BY pID) AS T3
ON T3.pID = P.pID
LEFT JOIN
(SELECT pID, COUNT(*) AS NB4 FROM Table4 GROUP BY pID) AS T4
ON T4.pID = P.pID
LEFT JOIN
(SELECT pID, COUNT(*) AS NB5 FROM Table5 GROUP BY pID) AS T5
ON T5.pID = P.pID
如果您希望在结果中包含除COUNT(*)
之外的其他聚合,而不必运行更多相关子查询,这将非常有用。