簡體   English   中英

SQL Server為什么不使用索引

[英]SQL Server why index is not used

我在SQL Server 2008數據庫中有一個下表:

CREATE TABLE [dbo].[Actions](
    [ActionId] [int] IDENTITY(1,1) NOT NULL,    
    [ActionTypeId] [int] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Description] [nvarchar](1000) NOT NULL,
    [Comment] [nvarchar](500) NOT NULL,
    [Created] [datetime] NOT NULL,
    [Executed] [datetime] NULL,
    [DisplayText] [nvarchar](1000) NULL,    
    [ExecutedBy] [int] NULL,
    [Result] [int] NULL
)   
CONSTRAINT [PK_Actions] PRIMARY KEY CLUSTERED 
(
    [CaseActionId] ASC
)
) ON [PRIMARY]

GO


CREATE NONCLUSTERED INDEX [IX_Actions_Executed] ON [dbo].[Actions] 
(
    [Executed] ASC,
    [ExecutedBy] ASC
)

有20 000行執行日期等於'2500-01-01'和420 000行執行日期<'2500-01-01'。

當我執行查詢時

select CaseActionId, Executed, ExecutedBy, DisplayText from CaseActions
where Executed='2500-01-01'  

查詢計划顯示執行PK_Actions上的聚簇索引掃描,並且IX_Actions_Executed不使用索引IX_Actions_Executed

我錯過了什么有趣的索引提示說

/* The Query Processor estimates that implementing the following index could improve the query cost by 99.9901%.
*/

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Actions] ([Executed])

但該指數已經存在。

如果選擇5%的數據,為什么不使用索引?

最有可能的是,查詢優化器只是看到你正在選擇DisplayText - 所以對於NC索引中找到的20'000行中的每一行,都需要對聚集索引進行密鑰查找才能獲得該數據 - 以及密鑰查找是昂貴的操作! 因此,最終,立即掃描clustere索引可能會更容易,也更有效。

我打賭如果你在這里運行這個查詢:

select CaseActionId, Executed, ExecutedBy
from CaseActions
where Executed='2500-01-01'

然后將使用NC索引

如果你確實需要DisplayText並且這是一個經常運行的查詢,那么你可能應該在索引中將該列作為葉級別的額外列包含在內:

DROP INDEX [IX_Actions_Executed] 

CREATE NONCLUSTERED INDEX [IX_Actions_Executed] 
ON [dbo].[Actions]([Executed] ASC, [ExecutedBy] ASC)
INCLUDE([DisplayText])

這將使您的NC索引成為覆蓋索引 ,即它可以返回查詢所需的所有列。 如果你使用這個覆蓋索引再次運行原始查詢,我很確定SQL Server的查詢優化器確實會使用它。 如果NC索引是覆蓋索引,則任何NC索引將被使用的概率顯着增加,例如,一些查詢可以從NC索引獲得他們需要的所有列,而無需密鑰查找。

丟失的索引提示有時會有點誤導 - 還有一些已知的錯誤導致SQL Server Mgmt Studio連續推薦已經存在的索引.....不要在這些索引提示上下注過多的錢!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM