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

oracle中模拟enq TX - index contention 及解决方案

原创 四九年入国军 2024-08-21
391
sqlplus scott/oracle


一、创建测试表、序列和脚本

create table tmp1(id varchar2(1000)); create index idx_tmp1 on tmp1(id) ; create sequence testseq increment by 1 start with 10001 maxvalue 999999999 cycle cache 500000; cat insert_date.sh #!/bin/bash for((i=1;i<=100;i++)); do ( sqlplus -S /nolog <<EOF conn scott/oracle begin for c_f in ( select level as id from dual connect by level <=10000) loop insert into tmp1 values(testseq.NEXTVAL); commit; end loop; end; / exit EOF )& done wait

二、模拟100并行插入

--1>场景一:未做任何优化,模拟100并行插入

sh insert_date.sh col event for a30 set linesize 1000 select event,count(1) from gv$active_session_history a where sample_time >=to_date('20240820 16:44:35','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 16:48:03','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2' group by event order by count(1); EVENT COUNT(1) ------------------------------ ---------- cursor: pin S 1 enq: TX - allocate ITL entry 2 latch: enqueue hash chains 7 latch: cache buffers chains 8 library cache: mutex X 23 latch: In memory undo latch 50 216 buffer deadlock 224 enq: TX - index contention 4156 buffer busy waits 12627 select count(1) from gv$active_session_history a where sample_time >=to_date('20240820 16:44:35','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 16:48:03','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2'; COUNT(1) ---------- 17314

--2>场景二:修改为反向索引,模拟100并行插入

--重建测试表 drop table tmp1; create table tmp1(id varchar2(1000)); create index idx_tmp1 on tmp1(id) reverse; --重建序列 drop sequence testseq; create sequence testseq increment by 1 start with 10001 maxvalue 999999999 cycle cache 500000; select event,count(1) from gv$active_session_history a where sample_time >=to_date('20240820 16:54:29','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 16:56:30','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2' group by event order by count(1); EVENT COUNT(1) ---------------------------------------- ---------- enq: TX - index contention 252 latch free 368 library cache: mutex X 504 535 latch: In memory undo latch 551 latch: redo copy 748 buffer busy waits 2371 select count(1) from gv$active_session_history a where sample_time >=to_date('20240820 16:54:29','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 16:56:30','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2'; COUNT(1) ---------- 5700

--3>场景三:修改为全局hash分区索引,模拟100并行插入

--分区索引测试 --新建索引分区测试insert并行速度 drop table tmp1; create table tmp1(id varchar2(1000)); create index idx_tmp1 on tmp1(id) global partition by hash(id) partitions 10; --创建序列 drop sequence testseq; create sequence testseq increment by 1 start with 10001 maxvalue 999999999 cycle cache 500000; select event,count(1) from gv$active_session_history a where sample_time >=to_date('20240820 17:04:31','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 17:07:32','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2' group by event order by count(1); EVENT COUNT(1) ---------------------------------------- ---------- latch: In memory undo latch 218 library cache: mutex X 218 260 buffer deadlock 656 enq: TX - index contention 1929 buffer busy waits 5544 select count(1) from gv$active_session_history a where sample_time >=to_date('20240820 17:04:31','yyyymmdd hh24:mi:ss') and sample_time <=to_date('20240820 17:07:32','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2'; COUNT(1) ---------- 9005

--4>场景四:修改为全局hash分区索引+调整表的PCTFREE,模拟100并行插入

--消除 buffer busy waits --新增pctfree和反向索引 --新建索引分区测试insert并行速度 drop table tmp1; create table tmp1(id varchar2(1000)); ALTER TABLE tmp1 pctfree 50; create index idx_tmp1 on tmp1(id) reverse; --创建序列 drop sequence testseq; create sequence testseq increment by 1 start with 10001 maxvalue 999999999 cycle cache 500000; select event,count(1) from gv$active_session_history a where sample_time >=to_date('20240820 17:30:37','yyyymmdd hh24:mi:ss') and sample_time <= to_date('20240820 17:32:05','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2' group by event order by count(1); EVENT COUNT(1) ---------------------------------------- ---------- enq: TX - index contention 292 latch: In memory undo latch 318 library cache: mutex X 361 451 latch: redo copy 637 buffer busy waits 1730 select count(1) from gv$active_session_history a where sample_time >=to_date('20240820 17:30:37','yyyymmdd hh24:mi:ss') and sample_time <= to_date('20240820 17:32:05','yyyymmdd hh24:mi:ss') and sql_id='gs8gm0c1gx8p2'; COUNT(1) ---------- 4400 --实验证明 调整 pctfree可以缓解 buffer busy waits

三、总结:

普通索引: 总等待17314秒,其中enq: TX - index contention 4156秒,buffer busy waits 12627秒 反向索引: 总等待5700秒, 其中enq: TX - index contention 252秒,buffer busy waits 2371秒 分区索引: 总等待9005秒, 其中enq: TX - index contention 1929秒,buffer busy waits 5544秒 反向+pctfree :总等待4400秒, 其中enq: TX - index contention 292秒,buffer busy waits 1730秒 总结:enq: TX - index contention 可以通过创建反向索引和分区索引来缓解,其中反向索引效果最好。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论