Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 带子行的T-SQL选择存在优化_Tsql_Optimization_Rows_Exists - Fatal编程技术网

Tsql 带子行的T-SQL选择存在优化

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

我正试图优化我的查询。基本上我有一个部门表和一个文档表。每个文档都属于一个部门,每个文档都可以是特定的类型

当前的mu查询如下所示

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)