覆盖索引是在所有为满足SQL查询不用到到达基本表所需的列上建立起来的非聚簇索引,如果查询查询遇到一个索引并且完全不需要引用底层数据表,那么该索引可以被认为是覆盖索引。
简单的可以理解为,我们所需要查询的列包含在了建立的非聚簇索引里。
下面我利用ADVENTUREWORKS数据库建立测试环境:
USE AdventureWorks go set statistics io on go select a.postalcode from person.address as a where a.stateprovinceID=42
--消息:
表'Address'。扫描计数1,逻辑读取18 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
创建索引:
1 create Nonclustered index [IX_ADDRESS_StateProvinceID] on 2 person.address(stateprovinceID ) 3 include (postalcode) 4 with( 5 drop_existing=on 6 ) 7 重新执行查询语句: 8 USE AdventureWorks 9 go 10 set statistics io on 11 go 12 select 13 a.postalcode 14 from person.address as a 15 where a.stateprovinceID=42
--消息
(8 行受影响)
表'Address'。扫描计数1,逻辑读取2 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
执行计划:
从反馈的消息里很容易看出买,逻辑读从18下降到2,做了很明显的改善了。
键查找和RID查找统称为书签查找,出现书签查找反而代表着性能低下,有些情况下甚至有着比表扫描更低的效率,因此我们应该尽量避免书签查找,数据量小的情况下,书签查找对性能影响不大,但是数据量大的情况下,书签查找对性能影响很严重。