如何在SQL Server上优化以下更新查询?

Ser*_*iev 5 sql sql-server performance

我需要在SQL Server 2005/2008上优化以下更新查询:

UPDATE
dbo.TargetTable A
SET
TargetColumn = 0
WHERE
TargetColumn = 1
AND 1 =
(
    SELECT COUNT(*)
    FROM dbo.TargetColumn B
    WHERE
                A.Id1 = B.Id1
                AND A.Id2 = B.Id2
                AND A.Id3 = B.Id3
)
Run Code Online (Sandbox Code Playgroud)

关于表dbo.TargetTable:它有大约100列和8个非聚簇索引.没有索引由Id1,Id2,Id3组成,并且包括TargetColumn.

我尝试在3种索引组合上运行此更新(表的大小约为200000条记录):

  1. 禁用所有索引
  2. 启用了所有8个索引
  3. 除了旨在加速更新的特殊索引之外,所有索引都被禁用:

在dbo上创建索引idx0.TargetTable(Id1,Id2,Id3)include(TargetValue)

我得到以下时间:

  1. 7分钟
  2. 5分钟
  3. 53秒

但后来我在桌面上尝试了这个查询,大小大约有1000万条记录,没有一个案例能够完成.在每种情况下,SQL Server都给出了关于缓冲池内存不足的奇怪错误.

除了使用特殊索引之外,还有其他方法可以优化此查询吗?

Lie*_*ers 5

我相信以下更新是等效的......

UPDATE  dbo.TargetTable
SET     TargetColumn = 0
FROM    dbo.TargetTable A
        INNER JOIN (
          SELECT  A.Id1
                  , A.Id2
                  , A.Id3
          FROM    dbo.TargetTable A
                  INNER JOIN dbo.TargetColumn B ON A.Id1 = B.Id1
                                                   AND A.Id2 = B.Id2 
                                                   AND A.Id3 = B.Id3
          GROUP BY
                  A.Id1
                  , A.Id2
                  , A.Id3
          HAVING  COUNT(*) = 1
        ) B ON B.Id1 = A.Id1
               AND B.Id2 = A.Id2
               AND B.Id3 = A.Id3
WHERE   A.TargetColumn = 1      
Run Code Online (Sandbox Code Playgroud)

......以及以下覆盖指数带来的好处

CREATE INDEX IX_TARGETTABLE_ID1_ID2_ID3 ON dbo.TargetTable (Id1, Id2, Id3) INCLUDE (TargetColumn)
CREATE INDEX IX_TARGETCOLUMN_ID1_ID2_ID3 ON dbo.TargetColumn (Id1, Id2, Id3)
Run Code Online (Sandbox Code Playgroud)