免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: jiachunzhou

请教一个超小型表上索引的问题 [复制链接]

论坛徽章:
0
发表于 2013-01-15 23:16 |显示全部楼层
Sybase不建议在这种小表上建索引。

论坛徽章:
0
发表于 2013-01-15 23:34 |显示全部楼层
http://www.cnblogs.com/jinlongyu/archive/2010/11/18/1881191.html
一篇sybase索引的使用与优化的文章,与大家分享

论坛徽章:
0
发表于 2013-01-16 14:37 |显示全部楼层
本帖最后由 sybman 于 2013-01-16 15:09 编辑

这个话题确实不错,能够帮助大家深入了解ASE,看大家讨论得热火朝天,忍不住也想说几句。

这种情况下,如果所有数据都在一个data page里面,建index的话未必能起到预期的效果,
反而会造成额外的开销,如,额外的index存储空间,额外的index 维护开销。

需要补充一点的是,ASE的optimizer是cost based的(cost的构成中disk I/O会占比较大的比重),这种情况下,
即使建了index,optimizer它会根据系统内维护的统计信息,算出那种那种scan方法好(table scan/index scan),
所以,即使建了index, scan也不一定会使用。

顺便回答一下前面的几个问题,如下

> 如果这个表只有两条记录,记录1的数据为10,记录2的数据为20
> 当事务A在更改记录1的数据,比如改为11,事务B还能将记录2的数据改为22么?
> 事务B是否需要等待事务A完成后才能进行更改?

如果lock scheme使用了datarows, 即使A没有提交,B是可以将2的纪录改为22的。

为什么呢,B不是需要扫描1的数据么,难道不会被Ablock么?这么认为很正常,不过不知道大家是否还记得,随着DOL的
引入,ASE内部也引入了一种新的lock 类型,叫做LATCH,它不是tansactional的,每当需要修改数据的时候,ASE会加
transactional的logical page/row lock,同时还会加上一个latch,latch在transaction内会被释放,而logical lock
直到tran提交或者回滚才被释放。

回到这个问题上来,当A完成了修改,未提交,这个时候A在纪录1上有一把ex row的排它锁,B会扫描整个表来寻找需要
更新的数据,扫描到纪录1的时候,会加上一个latch(可以顺利获得),然后比较是否是否符合条件。如符合,会在纪录1
上加update lock(会block);如不符合,B会继续比较记录2,如果记录2符合条件,纪录2上加update lock,接下来
在update过程中升级为 ex row 锁(可以顺利获得),所以B是不会被block的。

> 如果没有索引,那么在事务B在update的时候,where条件不会导致全表扫描么?

为了找到所有需要update的data rows,需要一次全表扫描。

论坛徽章:
0
发表于 2013-01-17 15:11 |显示全部楼层
乖乖,三位大哥都现身了。~学习之~

论坛徽章:
0
发表于 2013-01-18 19:53 |显示全部楼层
回复 13# sybman


回到这个问题上来,当A完成了修改,未提交,这个时候A在纪录1上有一把ex row的排它锁,B会扫描整个表来寻找需要
更新的数据,扫描到纪录1的时候,会加上一个latch(可以顺利获得),然后比较是否是否符合条件。如符合,会在纪录1
上加update lock(会block);如不符合,B会继续比较记录2,如果记录2符合条件,纪录2上加update lock,接下来
在update过程中升级为 ex row 锁(可以顺利获得),所以B是不会被block的。

我这里有两个问题:
1.首先我觉得,这个Latch肯定是给一个内存中的Page加的,应该是DB为了保证多线程对相同一块page进行操作而做的保护工作,和事务关系不大
   通过dbcc打印一个page的信息的时候,会有如下的一段话:

Latch and the wait queue:
Latch (address: 0x1bdc20030)
        latchmode: 0x0 (FREE_LATCH)  这里应该是 Latch的类型
        latchowner: 0
        latchnoofowners: 0
        latchwaitq: 0x0        latchwaitqt: 0x0

Latch wait queue:

2. 上面您说的A在对记录1更新,持有EX-row锁,B需要扫描记录1,并且记录1不是事务B需要修改的记录时,就不会出现Ex-row-blk的现象
    可是我这边有一个疑问,那个时候事务A不是正在对记录1进行操作么,事务B是如何知道记录1是否是自己需要的记录呢?不会出现脏读现象么,具体ASE会是怎么做的呢?
^_^




   

论坛徽章:
0
发表于 2013-01-25 13:39 |显示全部楼层
> 1.首先我觉得,这个Latch肯定是给一个内存中的Page加的,应该是DB为了保证多线程对相同一块page进行操作而做的保护工作,和事务关系不大

正解。

FREE_LATCH 表示此刻page上无latch,SH_LATCH/EX_LATCH 表示有latch。



至于脏读的问题,可能我前面没有说太清楚,补充一些内容。


针对这个case,可以分两种情况

1. 前面我提到的 B 不用等待 A 就可以 update 纪录1 里面的纪录基于如下的sql


create table t1(c1 int, c2 int) lock datarows
go

insert t1 values(1, 1)
insert t1 values(2, 1)
go

task A
------
begin tran
update t1 set c2 = 11 where c1 = 1
go

task B
======
begin tran
update t1 set c2 = 12 where c1 = 2
go

这种情况下 c1 并未受 A 的update的影响, 并且纪录1种的c1也不符合B的update条件,所以即使此时A在纪录1
上有EX_ROW锁, B 也不会block。


2. 但是在另一种情况下就不一样了,这个时候B就会block了,等到A提交或者rollback后才能继续。

create table t1(c1 int) lock datarows
go

insert t1 values(1)
insert t1 values(2)
go

task A
------
begin tran
update t1 set c1 = 11 where c1 = 1
go

task B
======
begin tran
update t1 set c1 = 12 where c1 = 2
go

A完成update后(提交或者回滚事务之前), 会在纪录1上有EX_ROW锁,这个时候,由于c1已经受到了A的影响,
而且B发现纪录1中的纪录 (c1)正在被更改,就会试图在纪录1上加锁,并被block。

论坛徽章:
0
发表于 2013-01-25 22:29 |显示全部楼层
回复 16# sybman

好的,十分感谢

我明白了,这里的重点在于update的时候,c1其实只是作为一个标志位存在的,不受事务的影响,可以不用考虑,也就不涉及到脏读的问题

在第二个例子里面,c1本身需要发生改变,于是B事务就会被blk住,那么A加的锁也就变成了 Ex-Row-blk了

3X大神~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP