- 最后登录
- 2015-1-5
- 在线时间
- 463 小时
- 威望
- 6
- 金钱
- 960
- 注册时间
- 2012-6-27
- 阅读权限
- 10
- 帖子
- 80
- 精华
- 0
- 积分
- 6
- UID
- 538
|
1#
发表于 2013-12-13 11:07:26
|
查看: 4976 |
回复: 3
本帖最后由 dla001 于 2013-12-13 11:10 编辑
insert ,update 绑定变量非常多的情况下。会产生很多的version_count。
同事问我,是否能只用一个version_count。因为一个执行非常频繁的SQL绑定变量有150多个。
查过很多资料,产生的原因是变量分级导致的。在做试验时,发现个有意思的事。
这个是解决insert,update绑定version_count多的方法吗?
环境如下:
环境:1
DB:11.2.0.3.7 x64
OS:OEL5.8 x64
修改过的隐藏参数
NAME VALUE ISDEFAULT ISMOD ISADJ
-------------------------------------------------- ------------------------- --------------------------- ------------------------------ ---------------
_disable_cursor_sharing FALSE TRUE FALSE FALSE
_optimizer_adaptive_cursor_sharing FALSE FALSE FALSE FALSE
_optimizer_extended_cursor_sharing NONE FALSE FALSE FALSE
_optimizer_extended_cursor_sharing_rel NONE FALSE FALSE FALSE
其它参数未改变
环境:2
DB:11.2.0.3.7 x64
OS:CentOS5.7 x64
没有修改隐藏参数
实验如下:- create table from_small_to_big( c1 varchar2(2001),c2 varchar2(2001),c3 varchar2(2001));
- create table from_big_to_small( c1 varchar2(2001),c2 varchar2(2001),c3 varchar2(2001));
- declare
- x varchar2(2001);
- y varchar2(2001);
- z varchar2(2001);
- begin
- x := rpad('A',32,'A');
- y := rpad('A',32,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',32,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- x := rpad('A',32,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',33,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- x := rpad('A',2001,'A');
- y := rpad('A',2001,'A');
- z := rpad('A',2001,'A');
- execute immediate 'insert into from_small_to_big values( :x, :y, :z)' using x, y, z;
- commit;
- end;
- /
- declare
- x varchar2(2001);
- y varchar2(2001);
- z varchar2(2001);
- begin
- x := rpad('A',2001,'A');
- y := rpad('A',2001,'A');
- z := rpad('A',2001,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',33,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- x := rpad('A',32,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',32,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- x := rpad('A',32,'A');
- y := rpad('A',32,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into from_big_to_small values( :x, :y, :z)' using x, y, z;
- commit;
- end;
- /
- set linesize 200
- col sql_text for a100
- select sql_id,sql_text,version_count,executions from v$sqlarea where sql_text like 'insert into from_big_to_small%' or sql_text like 'insert into from_small_to_big%';
- SQL_ID SQL_TEXT VERSION_COUNT EXECUTIONS
- --------------------------------------- ---------------------------------------------------------------------------------------------------- ------------- ----------
- gba4nq26jsfuw insert into from_small_to_big values( :x, :y, :z) 5 6
- 5210n56v52bsz insert into from_big_to_small values( :x, :y, :z) 1 6
复制代码 可以发现,一个version count为 5,另一个version count为1。
得出的结论是:
当第一个执行的SQL的变量的实际长度超过2000时,后面的SQL无论实际变量长度为多少,都不会产生新的version count 。实际会用4000字节来处理变量。
当变量长度由短变长时,会产生新的version count。 (参考变量分级 32 128 2000)
这也是为什么有的insert语句变量非常多,产生的version count也非常多的原因。
那么,我们是否可以这样做,手动插入一条SQL,将所有的变量都给最大值,这样后面的SQL就不会再产生新的version count ?
测试如下:- create table less_version_count( c1 varchar2(2001),c2 varchar2(2001),c3 varchar2(2001));
- declare
- x varchar2(2001);
- y varchar2(2001);
- z varchar2(2001);
- begin
- x := rpad('A',32,'A');
- y := rpad('A',32,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- --- 在这里,我们插入全为2001长度的变量,之后无论变量实际长度怎么变,都不应该产生新的version count
- x := rpad('A',2001,'A');
- y := rpad('A',2001,'A');
- z := rpad('A',2001,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- x := rpad('A',32,'A');
- y := rpad('A',33,'A');
- z := rpad('A',32,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- x := rpad('A',33,'A');
- y := rpad('A',33,'A');
- z := rpad('A',33,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- x := rpad('A',129,'A');
- y := rpad('A',129,'A');
- z := rpad('A',2000,'A');
- execute immediate 'insert into less_version_count values( :x, :y, :z)' using x, y, z;
- commit;
- end;
- /
- SQL_ID SQL_TEXT VERSION_COUNT EXECUTIONS
- --------------------------------------- ---------------------------------------------------------------------------------------------------- ------------- ----------
- gba4nq26jsfuw insert into from_small_to_big values( :x, :y, :z) 5 6
- 5j0ccy2ytwhk6 insert into less_version_count values( :x, :y, :z) 2 6
- 5210n56v52bsz insert into from_big_to_small values( :x, :y, :z) 1 6
复制代码 结论:如果遇到insert,update version_count 非常多的SQL,可以手动插入数据,来解决version_count很多的情况?
是否还有没考虑全的地方?
update 没测试,只是猜测的。 |
|