我有下表,其中包含750万条记录:
CREATE TABLE [dbo].[TestTable](
[Id] [int] IDENTITY(1,1) NOT NULL,
[TestCol] [nvarchar](50) NOT NULL,
[TestCol2] [nvarchar](50) NOT NULL,
[TestCol3] [nvarchar](50) NOT NULL,
[Anonymised] [tinyint] NOT NULL,
[Date] [datetime] NOT NULL,
CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
我注意到,当日期字段上存在非聚集索引时:
CREATE NONCLUSTERED INDEX IX_TestTable_Date ON [dbo].[TestTable] ([Date])
-并且我运行以下查询:
UPDATE TestTable
SET TestCol='*GDPR*', TestCol2='*GDPR*', TestCol3='*GDPR*', Anonymised=1
WHERE [Date] <= '25 August 2016'
-索引访问操作返回的数据经过排序,以匹配PK / CX的键顺序,从而降低了性能。
我很惊讶地发现从日期字段中删除索引实际上将查询性能提高了约30%,因为它不再执行排序:
我的理论(这对您中比较有经验的人来说可能是显而易见的)是,它发现date列的隐式排序与主键/聚簇索引完全相同。
所以我的问题是:是否可以利用这一事实来提高查询的性能?
[Date]
按DESC
顺序重新创建索引?只是好奇,因为谓词是<=
。此外,如果索引Date
(默认情况下ACS
为order)对其他查询有所帮助,那么您可以尝试向UPDATE添加表提示以强制其使用PK?或者,可以将其分为两部分:创建一个临时表,使用[Id]
基于填充[Date] <= '25 August 2016'
,然后WHERE
从UPDATE中删除并添加FROM dbo.TestTable tt INNER JOIN #tmp ids ON ids.[Id] = tt.[Id]
。毕竟,它是一个UPDATE,它需要查找实际的行,索引或否。