Tsql 带子行的T-SQL选择存在优化
我正试图优化我的查询。基本上我有一个部门表和一个文档表。每个文档都属于一个部门,每个文档都可以是特定的类型 当前的mu查询如下所示Tsql 带子行的T-SQL选择存在优化,tsql,optimization,rows,exists,Tsql,Optimization,Rows,Exists,我正试图优化我的查询。基本上我有一个部门表和一个文档表。每个文档都属于一个部门,每个文档都可以是特定的类型 当前的mu查询如下所示 SELECT DepartmentID, [Description] = DepartmentNo + ' (' + DepartmentName + ')', hasInvoice = CASE WHEN EXISTS(SELECT DocID FROM Document WHERE DepartmentID = Departme
SELECT DepartmentID,
[Description] = DepartmentNo + ' (' + DepartmentName + ')',
hasInvoice = CASE WHEN EXISTS(SELECT DocID FROM Document WHERE DepartmentID = Department.DepartmentID AND TypeID = 1) > 0 THEN 1 ELSE 0 END,
hasCreditNote = CASE WHEN EXISTS(SELECT DocID FROM Document WHERE DepartmentID = Department.DepartmentID AND TypeID = 2) > 0 THEN 1 ELSE 0 END,
hasQuote = CASE WHEN EXISTS(SELECT DocID FROM Document WHERE DepartmentID = Department.DepartmentID AND TypeID = 3) > 0 THEN 1 ELSE 0 END
FROM Department
ORDER BY DepartmentName
我遇到的问题是,每次按文档类型查找与部门相关的文档时,都会导致查询在文档表中重新扫描,这使得查询速度非常慢。有没有一种更优化的方法?我试过使用CTE,对每种类型进行左连接。但这似乎对加快查询速度没有影响
我们有大约200000个文档,所以优化这个查询是非常重要的
谢谢无论索引是什么,您在文档表上的“触碰”次数太多了:部门表中每行3次。因此,它的伸缩性很差,而且优化程序可能不会将相关子查询更改为联接 您可以使用连接在文档表上进行一次“触摸”,如下所示
SELECT
D.DepartmentID,
[Description] = D.DepartmentNo + ' (' + D.DepartmentName + ')',
hasInvoice = SIGN(COUNT(CASE WHEN doc.TypeID = 1 THEN 1 END)),
hasCreditNote = SIGN(COUNT(CASE WHEN doc.TypeID = 2 THEN 1 END)),
hasQuote = SIGN(COUNT(CASE WHEN doc.TypeID = 3 THEN 1 END))
FROM
Department D
LEFT JOIN
Document doc ON D.DepartmentID = doc.DepartmentID
ORDER BY
D.DepartmentName, D.DepartmentID, D.DepartmentNo
您还可以在筛选+聚合的文档派生表上左联接3次,或使用交叉应用3次:但这仍然是文档表的3次使用
对于任何解决方案,都需要在文档中的部门ID、TypeID
上建立索引。没有这个,我只能这么说
我假设Department.DepartmentID也是一个聚集索引。无论索引是什么,您在文档表上的“接触”次数太多:Department表中每行3次。因此,它的伸缩性很差,而且优化程序可能不会将相关子查询更改为联接 您可以使用连接在文档表上进行一次“触摸”,如下所示
SELECT
D.DepartmentID,
[Description] = D.DepartmentNo + ' (' + D.DepartmentName + ')',
hasInvoice = SIGN(COUNT(CASE WHEN doc.TypeID = 1 THEN 1 END)),
hasCreditNote = SIGN(COUNT(CASE WHEN doc.TypeID = 2 THEN 1 END)),
hasQuote = SIGN(COUNT(CASE WHEN doc.TypeID = 3 THEN 1 END))
FROM
Department D
LEFT JOIN
Document doc ON D.DepartmentID = doc.DepartmentID
ORDER BY
D.DepartmentName, D.DepartmentID, D.DepartmentNo
您还可以在筛选+聚合的文档派生表上左联接3次,或使用交叉应用3次:但这仍然是文档表的3次使用
对于任何解决方案,都需要在文档中的部门ID、TypeID
上建立索引。没有这个,我只能这么说
我假设Department.DepartmentID也是一个聚集索引。您在表中设置了哪些索引?是的。它不应该“重新扫描”。执行计划是否确实显示了这一点?理想情况下,您希望在
文档(DepartmentID,TypeID)
表上设置了哪些索引?是的。它不应该“重新扫描”。执行计划是否确实显示了这一点?理想情况下,您希望在文档(DepartmentID,TypeID)