sql-server - 在 SQL Server 2005 中的大表上更新为 "not in"

标签 sql-server indexing

我有一个包含大约 115k 行的表。像这样:

Table: People
Column: ID PRIMARY KEY INT IDENTITY NOT NULL
Column: SpecialCode NVARCHAR(255) NULL
Column: IsActive BIT NOT NULL

最初,我有一个这样定义的索引:

PK_IDX (clustered) -- clustered index on primary key
IDX_SpecialCode (non clustered, non-unique) -- index on the SpecialCode column

我正在做这样的更新:

Update People set IsActive = 0 
Where SpecialCode not in ('...enormous list of special codes....')

这个庞大的列表基本上包含表中 99% 的用户。

此更新在我的服务器上永远。作为测试,我将“not in”子句中的特殊代码列表修剪为大约表中 1% 的用户,我的执行计划最终使用 PK_IDX 索引上的 INDEX SCAN 而不是我使用的 IDX_SpecialCode 索引以为会用。

所以,我想也许我需要修改 IDX_SpecialCode,以便它在其中包含列“IsActive”。我这样做了,但我仍然看到执行计划默认为 PK_IDX 索引扫描,我的查询仍然需要很长时间才能运行。

那么 - 进行这种性质的更新更正确的方法是什么?我有我想从更新中排除的用户列表,但我试图避免从数据库中加载所有员工的特殊代码,在我的应用程序端过滤掉那些不在我的列表中的代码,然后运行我的查询带有 in 子句,在我的实际使用中这将是一个小得多的列表。

谢谢

最佳答案

如果您有要排除的员工,为什么不使用这些 PK_ID 填充索引表并执行以下操作:

Update People 
set IsActive = 0 
Where NOT EXISTS (SELECT NULL
                  FROM lookuptable l
                  WHERE l.PK = People.PK)

您正在进行索引扫描,因为 SQL Server 并不愚蠢,并且意识到只查看整个表而不是一次检查 100 个不同的条件更有意义。如果您的统计信息是最新的,优化器就会知道您的 IN 语句覆盖了多少表,如果它认为这样会更快,就会执行表或聚簇索引扫描。

关于sql-server - 在 SQL Server 2005 中的大表上更新为 "not in",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5435295/

相关文章:

sql - 在下一个未使用的索引处有序插入,通用 SQL

mysql - 查询的意外行为

javascript - Node/Express Rest API - 如何从 mssql 抛出错误

c# - Entity Framework Linq 查询 : runs instantly in SSMS and 8-10s in EF LINQ 出现问题

sql - Reporting Services 在哪里存储其日志文件

python - 如何在 Pandas 的查询中使用变量?

python - 为什么范围对象不能用于索引列表?

javascript - 确定下拉菜单的选定索引号?

SQL:将一行分成多行(规范化)

.net - System.Data.SqlClient.SqlParameter.IsNullable 的用途是什么?