暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

Update 影响 Select 效率示例

原创 布衣 2023-07-04
1520

1、背景

  DML操作不会影响SELECT操作,从接触数据库一直到今天我一直坚信着,今天以后再就不坚信了。

2、测试语句

create table t (id number,name varchar(20)); -- 插入100万条记录 begin for i in 1..1000000 loop insert into t values (i,'aaa'); end loop; commit; end; / -- 测试update 语句 update t set name = 'ccc' where id > 1 and id < 100000; -- 测试select 语句 select id from t where name = 'aaa';

3、测试操作

  • 未执行update ,select 查询效率:Elapsed: 00:00:06.34,consistent gets:68600
    image.png

  • sid:58 执行update 未提交
    image.png

  • sid:69 执行select 查看效率:Elapsed: 00:00:16.25,consistent gets:173801
    image.png

  • sid:58 对update 操作进行commit,再看sid:69的select 效率:Elapsed: 00:00:05.80,consistent gets 61670
    image.png
    image.png

  • 结论:从执行计划来看消耗都在consistent gets,前后对比执行时间差的近3倍左右。所以update在此种场景(特定的场景)会严重影响select效率。

3、如何避免

  • 这里简述一下逻辑读的概念:
    Logical read:逻辑读,就是从内存中读取数据块,包含Current read与Consistent read。
    Current read:属于Oracle版本读取方式的一种机制,就是说当进行DML操作时,我们需要获取数据块的最新状态,只对最新状态的块进行操作,操作期间锁定数据行。
    Consistent read:当进行select查询时,发现这个数据块的版本比我们要查找的要新,那么我们只能从UNDO中去查找这个数据的前映像(PRE IMAGE),在回滚段中找到这个数据的前映像后,把前映像和CURRENT的数据块合并,就形成一个CR BLOCK,这样,通过查询CR BLOCK就可以得到一致性的数据了,这就是Consistent read。(上面的测试,性能的影响基本都在这一块)

公式:logical read=db block gets(current read) + consistent gets(consistent read)。

  • 如何减少consistent gets?
    减少CR BLOCK的形成就能解决此类问题,前面的例子是update 完成所有的数据最后做的commit,所以后面的会话再做select 时需要形成非常多的CR BLOCK,从而影响到了查询效率。避免就是缩短update 这个会话的事务长度。

  • 有兴趣可以实验一下下面2个过程对select的影响。

-- 1. 长事务 begin for i in 1..100000 loop update t set name = 'ddd'||i where id = i; end loop; commit; end; / -- 2. 短事务 begin for i in 1..100000 loop update t set name = 'ddd'||i where id = i; commit; end loop; end; /

4、总结

  事务的长度与处理数据多少还是很影响查询的效率的。一定不要被自己的浅薄的认识迷惑了自己。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论