繁体   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