【发布时间】:2022-01-09 00:20:26
【问题描述】:
我有一个名为 Files 的表,其中包含这些列
[Id] [int] IDENTITY(1,1) NOT NULL,
[RowVersion] [timestamp] NULL,
[CreatedAt] [datetime2](7) NOT NULL,
[UpdatedAt] [datetime2](7) NOT NULL,
[FileName] [nvarchar](450) NOT NULL,
[FileContent] [nvarchar](max) NULL,
[MessengerId] [int] NOT NULL,
[FileTypeId] [int] NOT NULL,
[Ref] [int] NOT NULL,
该表在主键 Id 上有一个聚集索引。
在 MessengerId 和 FileName 上还有一个非聚集复合索引
CREATE UNIQUE NONCLUSTERED INDEX [IX_Files_CourierId_FileName] ON [dbo].[Files]
(
[MessengerId] ASC,
[FileName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
这个查询很慢
SELECT COUNT(*) FROM Files WHERE MessengerId = 1 AND Filename = 'myfilename.xml'
我正在努力测试,因为超时发生在生产服务器上。在我的开发笔记本电脑上,我没有任何问题。
在 MessengerId 和 Filename 上添加 2 个新索引会提高性能吗?
这 2 个新索引看起来像这样
CREATE NONCLUSTERED INDEX [Index_on_FileName] ON [dbo].[Files]
(
[FileName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
CREATE NONCLUSTERED INDEX [Index_on_MessengerId] ON [dbo].[Files]
(
[MessengerId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
GO
【问题讨论】:
-
当前索引是覆盖索引,可以用来满足您的查询,而无需在表中查找行。两个提议的索引都没有覆盖,因此查询将不得不求助于表查找/扫描来查找剩余数据。您的问题可能是过时的统计数据或参数嗅探。还可以阅读Slow in the Application, Fast in SSMS?
-
除了查询计划问题外,问题还可能是一般的服务器负载或持有行锁的应用程序(对于后者,您可以查看快照隔离等问题)。您唯一可以确定的不是问题是索引的有用性。如果您想知道(现有的或新的)索引是否有帮助,请始终查看之前和之后的查询计划;在这种情况下,应该告诉(即使在测试环境中)您的查询不会优先使用新索引而不是现有索引。
标签: sql-server indexing