2013-03-07 69 views
1

我有如下表:为什么这个查询中没有使用聚集索引?

CREATE TABLE [Cache].[Marker](
    [ID] [int] NOT NULL, 
    [SubID] [varchar](15) NOT NULL, 
    [ReadTime] [datetime] NOT NULL, 
    [EquipmentID] [varchar](25) NULL, 
    [Sequence] [int] NULL 
) ON [PRIMARY] 

用下面聚集索引:

CREATE UNIQUE CLUSTERED INDEX [IX_Marker_EquipmentID_ReadTime_SubID] ON [Cache].[Marker] 
(
    [EquipmentID] ASC, 
    [ReadTime] ASC, 
    [SubID] 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 

而这个查询:

Declare @EquipmentId nvarchar(50) 

Set @EquipmentId = 'KLM52B-MARKER' 

SELECT TOP 1 
    cr.C44DistId, 
    cr.C473RightLotId 
From Cache.Marker m 
    INNER JOIN Cache.vwCoaterRecipe AS cr ON cr.MarkerId = m.ID 
Where m.EquipmentID = @EquipmentId And m.ReadTime >= '3/1/2013' 
ORDER BY m.Id desc 

这里是正在生成的查询计划:

enter image description here

我的问题是这样的。为什么Cache.Marker表上的聚簇索引不是用于查找而是在另一个索引上进行扫描?此外,SSMS查询分析器建议我在包含ID和EquipmentID列的Marker.ReadTime上添加一个索引。

Cache.Marker表中大约有1M行。

+0

@pst - 我不跟着你。 – 2013-03-07 20:43:38

+1

你可以在查询中用'KLM52B-MARKER'代替@EquipmentID吗?你没有得到所需的索引变量? – bobs 2013-03-07 20:49:01

+3

为什么人们总是认为聚集索引始终是满足任何查询的最快方法? – 2013-03-07 20:59:31

回答

3

你有多少个独特的设备ID?这可能是决定日期是一个更好的第一次查找(可能是错误的)。您可以强制它使用您的索引,尽管WITH(INDEX())声明。 FORCESEEK也可以提供帮助。我强烈建议这样做,因为随着数据库规模扩大,索引行为是可预测的。

SELECT TOP 1 
    cr.C44DistId, 
    cr.C473RightLotId 
From Cache.Marker m 
    WITH (INDEX(IX_Marker_EquipmentID_ReadTime_SubID), FORCESEEK) 
    INNER JOIN Cache.vwCoaterRecipe AS cr 
    ON cr.MarkerId = m.ID 
Where m.EquipmentID = @EquipmentId And m.ReadTime >= '3/1/2013' 
ORDER BY m.Id desc 
+0

大致有24个独特的设备ID值。 – 2013-03-07 20:48:46

+1

hmm,24个独特的设备ID值可能表明选择性低。 – bobs 2013-03-07 20:49:58

+3

@RandyMinder只有24个不同的ID,SQL Server已经决定它不是很有选择性(一百万行)。感觉使用日期是一个更好的选择。同时测试。这往往是错误的。 – ThinkingStiff 2013-03-07 20:50:01

相关问题