外键上建立索引的好处

外键上建立索引的好处

 

在主从表设计中,常常使用外键在这两个表之间建立关联。当从主表中删除一行数据时,SQL Server便会检查从表中是否有相同外键的行存在。如果从表没有包含外键列的索引,SQL SERVER需要扫描整个从表。可以想象:从表越大,删除的时间越长。更新主表时的情况也是一样。

 

INSERT

DELETE

UPDATE

主表(被引用表)

不作检查

检查从表是否有该键值的引用

检查从表是否有旧键值的引用

 因为主表有唯一聚集或非聚集的索引,所以在从表中插入或修改时,能利用主表的索引快速定位。

 下面来举例说明:

先创建两个表:主表ta(col1, col2),从表tb(col3, col4, col5),tb表的col4列引用ta表的col1列。先不要再col4上创建索引。

if object_id('tb')isnot null

drop tabletb

go

if object_id('ta')isnot null

drop tableta

go

create tableta(col1intprimary key,col2 char(2000))

go

 createtabletb(col3intprimary key,col4 int,col5 char(2000)

constraint fk1 foreign key (col4)referencesta(col1)ondelete cascade

)

go

declare @i int

set @i= 1

while @i<=30000

begin

  insert into ta

  values(@i,@i)

   set @i=@i + 1

end;

go

 declare@i int

set @i= 1

while @i<=30000

begin

  insert into tb

  values(@i,@i,@i)

   set @i=@i + 1

end; 

执行ta上的删除动作,看看计划与IO:

dbcc dropcleanbuffers

go

dbcc freeproccache

go

set statisticsioon

set statisticstimeon

go

delete ta where col1 = 20087 

计划如下:

 

可以看出,由于没有col4上的索引,所以SQL SERVER只得在tb表上进行聚集索引扫描。IO如下:

SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 21 毫秒。

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

表'tb'。扫描计数1,逻辑读取7529 次,物理读取3 次,预读7521 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

表'Worktable'。扫描计数2,逻辑读取7 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

表'ta'。扫描计数0,逻辑读取3 次,物理读取3 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

  

下面在表tb的col4上创建一个非聚集索引,同样执行上面的删除动作,再看看结果:

create nonclusteredindexnc1 on tb(col4)

go

dbcc dropcleanbuffers

go

dbcc freeproccache

go 

set statisticsioon

set statisticstimeon

go 

delete ta where col1 = 20088


 

果然,SQL SERVER使用了索引查找。IO结果如下:

SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 14 毫秒。

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

表'tb'。扫描计数1,逻辑读取9 次,物理读取4 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

表'Worktable'。扫描计数2,逻辑读取7 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

表'ta'。扫描计数0,逻辑读取3 次,物理读取2 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

 对比两个IO结果,会发现在外键上建立索引大大节省了时间。

 参考文献

1.       http://www.sqlperformance.com/2012/11/t-sql-queries/benefits-indexing-foreign-keys

2.       http://msdn.microsoft.com/zh-cn/library/ms175464(v=sql.105).aspx

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值