TSQL 2008r2将索引更改为索引寻求不索引扫描

时间:2014-11-26 09:59:58

标签: performance tsql sql-server-2008-r2 indexing

MS SQL Server 2008r2

我需要以下索引搜索,而不是索引扫描。 此外,如果有人可以解释为什么不寻求,将不胜感激。

这是我的表

    IF OBJECT_ID('tempdb..#LogTbl') IS NOT NULL
        DROP TABLE #LogTbl
    CREATE TABLE #LogTbl(
         rNum       INT IDENTITY(1,1)
        ,LogID      INT NOT NULL
        ,NodeID     INT NOT NULL
        ,GPSTime    INT NOT NULL
        ,Speed      INT NULL
        ,RoadSpeed  INT NULL
        ,DriverNodeID INT NULL
        ,Category   VARCHAR(10)
        ,Points     INT     
        ,CatPoints  INT
    )
    ALTER TABLE #LogTbl ADD CONSTRAINT [PK_LogTbl1] PRIMARY KEY CLUSTERED ( rNum )

这是我的NonClustered Indexes

    CREATE NONCLUSTERED INDEX IDX_Log1 ON #LogTbl( RoadSpeed )
    CREATE NONCLUSTERED INDEX IDX_Log2 ON #LogTbl( rNum ) INCLUDE ( RoadSpeed, Speed )

此查询将在IDX_Log1

上进行索引搜索
    UPDATE #LogTbl SET RoadSpeed = 0 WHERE RoadSpeed IS NULL

但这只是IDX_Log2上的索引扫描

    UPDATE L
    SET RoadSpeed = CASE
                        WHEN L.RoadSpeed = 0 THEN 70
                        ELSE ROUND( L.RoadSpeed  * 0.621371192, 0 )
                    END
            ,Speed = ROUND( L.Speed  * 0.621371192, 0 )
    FROM #LogTbl L

Index Scan On IDX_Log2

我哪里错了?

1 个答案:

答案 0 :(得分:2)

很简单,没有什么可以寻求的。您的第一个查询有一个where子句:

WHERE RoadSpeed IS NULL;

由于RoadSpeed上有非聚簇索引,优化器可以在此索引中查找空行。在第二个查询中,您没有where子句,需要更新整个表,因此必须执行所有行的扫描。

对于它的价值,rnum上的非聚集索引很可能是多余的:

CREATE NONCLUSTERED INDEX IDX_Log2 ON #LogTbl( rNum ) INCLUDE ( RoadSpeed, Speed )

这是集群密钥,因此已经编入索引,并且包含列RoadSpeedSpeed(因为聚集索引是数据)。您的第二个非聚集索引基本上是此索引的副本,但更窄,因为您只有3列数据要存储。如果您的读/写很少,并且经常只使用这三列,那么索引可能值得,但在大多数情况下,维护这个额外索引的成本将超过它提供的轻微性能优势。