2013-03-20 64 views
0

我有如下表:可以为此查询创建什么索引?

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 
) 

CREATE NONCLUSTERED INDEX [IX_Marker_Id] ON [Cache].[Marker] 
(
    [ID] ASC 
) 
INCLUDE ([EquipmentID]) 

CREATE NONCLUSTERED INDEX [IX_Marker_SubID] ON [Cache].[Marker] 
(
    [SubID] ASC 
) 
INCLUDE ([EquipmentID],[ReadTime]) 

我执行以下查询:

Declare @EquipmentId varchar(50) 

SELECT TOP 1 
    C44DistId, 
    C471DistId, 
    C473RightLotId 
From Cache.vwMarker m 
    INNER JOIN Cache.vwCoaterRecipe AS cr ON cr.MarkerId = m.ID AND M.EquipmentID = @EquipmentId 
Order By m.Id Desc 

查询计划如下所示:

enter image description here

标记表有大约7M行,所以扫描相当昂贵。 7M行中只有24个唯一的EquipmentId值,这可能是扫描正在进行的原因。

此查询往往需要40+秒来执行,这取决于服务器的负载。我一直在想办法(通过创建某种索引)来让SQL Server在Marker表上查找。我一直未能拿出任何东西。也许没有办法,但我想我会先问。

回答

1

包含EquipmentIDId列的Marker表的唯一索引是IX_Marker_Id。由于此索引不具有EquipmentID作为第一列,因此您无法寻求;您必须以相反顺序扫描索引以找到匹配的第一个条目EquipmentID

像这样的东西可能会有所帮助:

CREATE NONCLUSTERED INDEX [IX_Marker_EquipmentID_Id] ON [Cache].[Marker] 
(
    [EquipmentID] ASC, 
    [ID] DESC 
) 

编辑:当然,你的聚集索引包括列,但只有24个不同EquipmentID值,它会扫描整个290000行找到最大Id。通过反向扫描IX_Marker_Id索引,只要发现匹配的EquipmentID就会停止,这可能会更快。