什么是索引连接?

0
已邀请:
0

戴俊青 - 微软数据库开发和性能调优 2013-07-26 回答

索引连接是索引交叉的变种,它是将覆盖索引的技术应用到索引交叉上,如果一个查询没有单个的覆盖索引,但有多个索引在一起可以覆盖该查询,sql server使用索引连接的方法,从而避免索引扫描(index scan)。
我们使用下面的语句来完成测试:
sp_help 'sales.SalesOrderHeader'
1.jpg

从上面表中可以看出,表sales.salesorderheader的索引情况,我们运行下面语句,查看他的查询计划和开销:
use adventureworks
go
set statistics io on
go
select
soh.salespersonID
, soh.orderdate
from sales.salesorderheader as soh
where soh.salespersonid=276
and soh.orderdate between '4/1/2002' and '7/1/2002'
消息:
表'SalesOrderHeader'。扫描计数1,逻辑读取703 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
执行计划:
2.jpg

优化器没有使用非聚集索引IX_SalesOrderHeader_SalesPersonID,而是使用了聚集索引PK_SalesOrderHeader_SalesOrderID,显然优化器认为走聚集索引使用的开销比使用非聚集索引IX_SalesOrderHeader_SalesPersonID要低。
下面我在where条件上的soh.orderdate列上建立一个非聚集索引,看看能有什么效果:
create nonclustered index IX_aa on sales.salesorderheader(orderdate)
查看一下索引:sp_help 'sales.SalesOrderHeader'
3.jpg

Orderdate列上的非聚集索引已经存在了,重新运行一下语句看看执行计划和开销。
use adventureworks
go
set statistics io on
go
select
soh.salespersonID
, soh.orderdate
from sales.salesorderheader as soh
where soh.salespersonid=276
and soh.orderdate between '4/1/2002' and '7/1/2002'
消息:
(27 行受影响)
表'Worktable'。扫描计数0,逻辑读取0 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
表'SalesOrderHeader'。扫描计数2,逻辑读取8 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。
执行计划:
4.jpg

很明显,查询的逻辑读取大幅度降低了,这两个非聚集索引组合起来达到覆盖索引的效果,从而使查询开销大幅度降低了。

要回复问题请先登录注册