日期:2014-05-18  浏览次数:20616 次

邹建大哥你在哪里~~~~~~~~~~~~~~~~~~~~
没办法了,只能请教您了。。。
2个会话。。。
/*创建表t1,c1列聚集索引,c2非聚集索引,c3无索引*/

会话1--> 死循环update表中的非聚集索引根据聚集索引
update   t1   set   c2   =   5   where   c1   =   5

会话2--> 死循环select   c2,c3(无任何索引)   from   t1   where   c2   between   3   and   300
检索数据后插入临时表,再执行truncate   table   临时表

执行1后紧接执行2后会发生死锁现象.......(即进程**为**的牺牲品...)

会话一   waiting   select****释放S锁,得到X锁
会话二   waiting   update的产生的锁

可是再执行几次后,发现死锁消失,查看了下锁进程发现select用的是覆盖索引,即显示的索引是(t1.t1)

可是我没有创建过覆盖索引。。。。

我的sqlserver是2000和2005一个实例


------解决方案--------------------
不明白你想说什么,覆盖索引应该是一个非聚集的复合索引
------解决方案--------------------
我的意思是select c2,c3(无任何索引) from t1 where c2 between 3 and 300
用的是c2列上的索引,而在锁进程中发现他用的索引是 t1.t1
这是为什么???
--------------------------------------------------

c3是无索引的, 所以必须访问基础表才能拿到 c3 的数据, 而无论条件是否通过索引过滤, 最终访问基础表的数据都必须经过聚集索引的(除非你的表上没有聚集索引)
------解决方案--------------------
对于有聚集索引的表数据存储而言, 所有的数据都是聚集索引的叶子结点, 所以如果访问的数据需要从基础表拿数据的话, 它一定经过聚集索引的扫描.