Sql-Server

未使用非聚集索引

  • March 7, 2018

我有一個包含 321 行的表(在下面創建)。

我希望下面的最後一個查詢使用非聚集索引,然後使用鍵查找。但是,它使用聚集索引掃描。僅按預期返回一行。

為什麼它進行掃描而不是使用非聚集索引?是因為表只包含 321 行嗎?

CREATE TABLE dbo.TestIndexSample
(
   Code char(4) NOT NULL,
   Name nvarchar(200) NOT NULL,
   ModifiedDate datetime NOT NULL CONSTRAINT [DF_TestIndexSample_ModifiedDate] DEFAULT GETDATE(),
   CONSTRAINT [PK_TestIndexSample_Code] PRIMARY KEY CLUSTERED(Code)
);
GO
CREATE NONCLUSTERED INDEX IX_TestIndexSample_Name  
   ON dbo.TestIndexSample(Name);   
GO

INSERT INTO dbo.TestIndexSample(Code, Name)
select CodeName, FullName 
from dbo.SourceTest 
GO

SELECT * FROM dbo.TestIndexSample

SELECT * FROM dbo.TestIndexSample where Code = 'X132EY'

SELECT * FROM dbo.TestIndexSample where Name = 'User A'

您可以強制 SQL Server 使用非聚集索引:

SELECT Code, Name, ModifiedDate 
FROM   dbo.TestIndexSample WITH(INDEX (IX_TestIndexSample_Name))
WHERE  Name = 'NAME10';

在此處輸入圖像描述

dbfiddle在這裡,計劃在這裡

如果沒有提示,查詢優化器會認為帶有索引的計劃對於少量數據來說成本更高,但是您可以通過增加表中的行數來獲得此計劃。我設法用 600 行來實現它:

SELECT Code, Name, ModifiedDate 
FROM   dbo.TestIndexSample 
WHERE  Name = 'NAME10';

dbfiddle在這裡

如果您只想獲取 Index Seek,您的查詢應該返回 only Name,以便僅從索引中提取數據。

SELECT Name 
FROM   dbo.TestIndexSample  
WHERE  Name = 'NAME10';

在此處輸入圖像描述

dbfiddle在這裡,計劃在這裡

但如果還需要返回其他列,則可以使用覆蓋索引:

CREATE NONCLUSTERED INDEX IX_TestIndexSample_Name  
   ON dbo.TestIndexSample(Name) INCLUDE (Code, ModifiedDate);

顯然索引大小會增加,但對於這個行數來說並不重要。

現在,您目前的查詢將使用 Index Seek:

SELECT Code, Name, ModifiedDate 
FROM   dbo.TestIndexSample 
WHERE  Name = 'NAME10';

在此處輸入圖像描述

dbfiddle在這裡,計劃在這裡

引用自:https://dba.stackexchange.com/questions/199487