我有两张桌子
CREATE TABLE [dbo].[T2] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[F1] NVARCHAR (100) NULL,
[F2] NVARCHAR (100) NULL,
[F3] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE NONCLUSTERED INDEX [IX_T2_F1_F2]
ON [dbo].[T2]([F1] ASC, [F2] ASC);
和
CREATE TABLE [dbo].[T3] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[F1] NVARCHAR (100) NULL,
[F2] NVARCHAR (100) NULL,
[F3] NVARCHAR (MAX) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO
CREATE NONCLUSTERED INDEX [IX_T3_F1_F2]
ON [dbo].[T3]([F1] ASC, [F2] ASC)
INCLUDE([F3]);
这些是我的执行计划
问题是为什么查询#2的执行计划不是Index Seek (NonClustered)
,为什么查询优化器选择扫描PK上的聚簇索引而不是非聚集索引{F1,F2}
?
更新#1:
答案 0 :(得分:2)
SELECT [F1],[F2],[F3] FROM [T2] WHERE ...
需要三列,而IX_T2_F1_F2
只包含其中两列。
当涉及覆盖不涵盖所需列的索引时,SQL Server有时会顽固不化。为了满足查询,它必须将覆盖索引与聚集索引结合使用,并且(简化一点)涉及的操作越多,查询成本就越高。
它估计扫描一个索引(聚集索引)比使用两个索引便宜,并且您获得了一个带有聚簇索引扫描的计划。
Here是一篇进一步讨论它的文章,SQL Server将在什么时候将覆盖索引与聚集索引结合使用。
答案 1 :(得分:1)
您的统计信息可能不是最新的。您可以使用查询提示强制SQL Server使用您的首选索引,例如(index(your_index_name))。我建议尝试使用此查询提示来检查索引的性能。