MSSQL聚集索引扫描 Scan Direction的两种方式--FORWARD 和 BACKWARD
Tags: MSSQLSQL Server索引扫描
最近发现一个分页查询存储过程中的的一个SQL语句,当聚集索引列的排序方式不同的时候,效率差别达到数十倍,让我感到非常吃惊
由此引发出来分页查询的情况下对大表做Clustered Scan的时候,
不同情况下会选择FORWARD 或者 BACKWARD差别,以及建立聚集索引时,选择索引列的排序方式的一些思考
废话不多,上代码
先建立一张测试表,在Col1上建立聚集索引,写入100W条数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | create table ClusteredIndexScanDirection ( Col1 int identity(1,1), Col2 varchar(50), Col3 varchar(50), Col4 Datetime ) create unique clustered index idx_Col1 on ClusteredIndexScanDirection(Col1 ASC) DECLARE @date datetime,@i int=0 set @date=GETDATE() while @i<1000000 begin insert into ClusteredIndexScanDirection values (NEWID(),NEWID(),DATEADD(MI,@i,GETDATE()-200)) set @i=@i+1 end |
先直观地看一下聚集索引扫描时候的FORWARD 和 BACKWARD
BACKWARD
执行如下分页查询,当按照Col4符合2017-7-18和2017-7-23,并且Col1 倒序排序的时候
从执行计划看,Clustered Index Scan的Scan Direction的方式是BACKWARD
FORWARD
执行如下分页查询,当按照Col4符合2017-7-18和2017-7-23,并且Col1 正序排序的时候
从执行计划看,Clustered Index Scan的Scan Direction的方式是FORWARD
查询条件一样,分页情况下,排序方式不一样,性能上有么有差别?肯定有,太明显了,如果没有,本文也就没有什么意义了
如图是上述两种查询方式在我本机的测试结果,同样是前100条数据,因为排序方式不同,其代价也是不同的
逻辑读,一个是2327,一个是9978次,差别不小吧,在实际场景中,这个差别是非常非常大的,大到足以超乎你想想
对FORWARD和BACKWARD有一个直观的感受之后,来说说这两者的区别
如果了解B树索引结构的话,应该知道聚集索引是以类似于B树结构的方式来组织的,既然是B树结构,
那么下面这个图就不难理解了,
在索引列按照某事方式排序的情况下,比如
1 2 3 | create unique clustered index idx_Col1 on ClusteredIndexScanDirection(Col1 ASC) 或者是 create unique clustered index idx_Col1 on ClusteredIndexScanDirection(Col1 DESC) |
下面这张图分别是FORWARD和BACKWARD两种Scan direction的实现方式
FORWARD
BACKWARD