1、什么是表扫描
当执行SQL 语句时,可通过“”评估执行计划”,查看语句的执行计划。尤其是语句设计查询,会出现“表扫描”部分;
表扫描是严重影响查询时间的因素!
2、验证
(1)新建数据表BasicMsg20161204,主键为自增列,但是将聚集索引建立在(RecvTime,AA,MsgTypecode)上;
(2)新建数据表BasicMsg20161104,主键为自增列,且该列为聚集索引;在RecvTime上有非聚集索引;
(3)新建数据表BasicMsg20161004,主键为自增列,且该列为聚集索引;没有任何其他索引。
表中共有347758行数据, 查看三表的IO读写情况:
--//----------------------------------------------
--1、查看该表的IO读写情况
DBCC DROPCLEANBUFFERS --清空所有的缓存区内容 SET STATISTICS IO ON SELECT * FROM BasicMsg20161204 --WHERE IDFlag=347758 SET STATISTICS IO OFF
--2、结果:
--BasicMsg20161204
--(347758 row(s) affected) --Table ‘BasicMsg20161204‘. Scan count 1, logical reads 6594, physical reads 2, read-ahead reads 6596, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. --扫描计数1次,逻辑读取6594次!物理读取2次,预读6594次,lob逻辑读取0次...--BasicMsg20161104
--(347758 row(s) affected)--Table ‘BasicMsg20161104‘. Scan count 1, logical reads 6575, physical reads 3, read-ahead reads 6596, --扫描计数1次,逻辑读取6575次!物理读取3次,预读6575次,lob逻辑读取0次...
--3、分析
发现,当未用WHERE 语句对索引列进行条件筛选时,前两表的逻辑读取都比较大,索引没有明显作用;未加任何索引的1004表的预读次数反而少;
(1)当在查询语句后加 WHERE RecvTime<=17999995限制条件,扫描次数一样
(2)当在查询语句后加 WHERE RecvTime=17999995限制条件,BasicMsg20161204表的结果为:Scan count 1, logical reads 3, physical reads 3;建立非聚集索引的BasicMsg20161104表为:Scan count 1, logical reads 3, physical reads 3;
未在RecvTime上加索引,1004表的Table ‘BasicMsg20161004‘. Scan count 9, logical reads 7215, physical reads 2, read-ahead reads 4352,与其他2表的3次和6次,有天壤之别!!
这说明,索引建立在需要具体判定条件的列上才有效。
--4、DBCC命令协助理解
dbcc ind 命令查看下数据表记录在哪个数据页中
DBCC IND(DF17DataPro,BasicMsg20161104 ,-1) -- (数据库名,表名,参数值)
然后导出该数据页
dbcc traceon(3604) dbcc page(Ctrip,1,148,1)