sql - 如何优化 SQL Server 上的以下更新查询?

标签 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
)

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

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

  1. 所有索引均已停用
  2. 全部 8 个索引已启用
  3. 除旨在加快更新速度的特殊索引外,所有索引均已禁用:

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

我得到以下时间:

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

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

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

最佳答案

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

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      

...并受益于以下 Covering Indexes

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)

关于sql - 如何优化 SQL Server 上的以下更新查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4202335/

相关文章:

php - 如何重新计算与另一个表相关的字段(Yii2 MySQL)

sql-server - 是否可以从 INFORMATION_SCHEMA 获取表类型定义?

sql - 特殊情况需要计数记录

c# - 如何优化大尺寸for循环

c - 提高我的 C 列表 push_back 函数的性能

java - Cypher 挂起,我们如何修复/重新设计?

php - 选择与时间戳相同的日期

sql - 查询一个表,将分组行中的某些列映射到同一行中的多个列

sql - 当我有一个很大的结果时,Postgres 函数不工作

sql - 传递包含多个 ID 的单个参数