[20131116]12c的EXTENDED VARCHAR2与隐含参数_scalar_type_lob_storage_threshold.txt
参考链接:http://space.itpub.net/267265/viewspace-776806/
google查询了一些资料:
发现:
SYS@test01p> @hide _scalar_type_lob_storage_threshold;
NAME DESCRIPTION DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE
---------------------------------------- ------------------------------------------------------------------ ---------------------- ---------------------- ----------------------
_scalar_type_lob_storage_threshold threshold for VARCHAR2, NVARCHAR2, and RAW storage as BLOB TRUE 4000 4000
--很明显这个参数可以控制字符串当作blob存储的长度,也就是缺省是4000.
--如果修改这个参数就可以控制存储长度是否选择blob方式保存的切换点。
SYS@test01p> alter system set "_scalar_type_lob_storage_threshold"=1048576;
System altered.
--奇怪设置很大的值,系统也能接受。
SYS@test01p> alter system set "_scalar_type_lob_storage_threshold"=6000;
System altered.
--这样长度小于等于6000的字符不会使用blob保存。
做一些测试看看:
SYS@test01p> @ver
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
drop table t1 purge ;
SCOTT@test01p> select * from user_lobs;
no rows selected
--当前用户没有lob字段类型。
create table t1 ( id number,a varchar2(5000),b varchar2(6000) ,c varchar2(6001) );
SCOTT@test01p> column segment_name format a30
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
-- 可以发现仅仅第4个字段可能会使用lob段。这样可以实现大于4000的一些字符保存在块内,或者形成行链接的情况。
--建立索引看看,当然一般情况不会在这么长的字符串建立索引,仅仅看看是否成功。
SCOTT@test01p> create index i_t1_b on t1(b);
Index created.
SCOTT@test01p> create index i_t1_c on t1(c);
Index created.
--也许没有段的分配,插入数据看看。一般ORA-01450错误: maximum key length (6398) exceeded,没有操作限制。
SCOTT@test01p> insert into t1 values (1,lpad('a',5000,'a'),lpad('b',6000,'b'),lpad('c',6001,'c'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
--OK没有问题。
--这些大于4000的字符索引是不能做rebuild online 操作的。
SCOTT@test01p> alter index i_t1_b rebuild online ;
alter index i_t1_b rebuild online
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded
SCOTT@test01p> alter index i_t1_c rebuild ;
Index altered.
--如果这时修改参数回来会出现什么情况呢?
SCOTT@test01p> alter system set "_scalar_type_lob_storage_threshold"=4000;
System altered.
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
SCOTT@test01p> insert into t1 values (2,lpad('a',5000,'a'),lpad('b',6000,'b'),lpad('c',6001,'c'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
--没有任何影响,T1表上没有建立新的段,因为前面表已经定义好了。
--当然这么长的字段建立索引没有意义,但是这个参数_scalar_type_lob_storage_threshold对于一些特殊需求还是不错的。
--比如如果应用中保存的字符串在4000上下,如果使用blob保存,8k的数据块至少浪费50%的空间,而设置
--_scalar_type_lob_storage_threshol=5000,可以很好的规避这些问题。
--当然这这些东西真要在生产系统使用还是要严格测试,谨慎使用!!
参考链接:http://space.itpub.net/267265/viewspace-776806/
google查询了一些资料:
发现:
SYS@test01p> @hide _scalar_type_lob_storage_threshold;
NAME DESCRIPTION DEFAULT_VALUE SESSION_VALUE SYSTEM_VALUE
---------------------------------------- ------------------------------------------------------------------ ---------------------- ---------------------- ----------------------
_scalar_type_lob_storage_threshold threshold for VARCHAR2, NVARCHAR2, and RAW storage as BLOB TRUE 4000 4000
--很明显这个参数可以控制字符串当作blob存储的长度,也就是缺省是4000.
--如果修改这个参数就可以控制存储长度是否选择blob方式保存的切换点。
SYS@test01p> alter system set "_scalar_type_lob_storage_threshold"=1048576;
System altered.
--奇怪设置很大的值,系统也能接受。
SYS@test01p> alter system set "_scalar_type_lob_storage_threshold"=6000;
System altered.
--这样长度小于等于6000的字符不会使用blob保存。
做一些测试看看:
SYS@test01p> @ver
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
drop table t1 purge ;
SCOTT@test01p> select * from user_lobs;
no rows selected
--当前用户没有lob字段类型。
create table t1 ( id number,a varchar2(5000),b varchar2(6000) ,c varchar2(6001) );
SCOTT@test01p> column segment_name format a30
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
-- 可以发现仅仅第4个字段可能会使用lob段。这样可以实现大于4000的一些字符保存在块内,或者形成行链接的情况。
--建立索引看看,当然一般情况不会在这么长的字符串建立索引,仅仅看看是否成功。
SCOTT@test01p> create index i_t1_b on t1(b);
Index created.
SCOTT@test01p> create index i_t1_c on t1(c);
Index created.
--也许没有段的分配,插入数据看看。一般ORA-01450错误: maximum key length (6398) exceeded,没有操作限制。
SCOTT@test01p> insert into t1 values (1,lpad('a',5000,'a'),lpad('b',6000,'b'),lpad('c',6001,'c'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
--OK没有问题。
--这些大于4000的字符索引是不能做rebuild online 操作的。
SCOTT@test01p> alter index i_t1_b rebuild online ;
alter index i_t1_b rebuild online
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3215) exceeded
SCOTT@test01p> alter index i_t1_c rebuild ;
Index altered.
--如果这时修改参数回来会出现什么情况呢?
SCOTT@test01p> alter system set "_scalar_type_lob_storage_threshold"=4000;
System altered.
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
SCOTT@test01p> insert into t1 values (2,lpad('a',5000,'a'),lpad('b',6000,'b'),lpad('c',6001,'c'));
1 row created.
SCOTT@test01p> commit ;
Commit complete.
SCOTT@test01p> select table_name,segment_name from user_lobs;
TABLE_NAME SEGMENT_NAME
---------- ------------------------------
T1 SYS_LOB0000093538C00004$$
--没有任何影响,T1表上没有建立新的段,因为前面表已经定义好了。
--当然这么长的字段建立索引没有意义,但是这个参数_scalar_type_lob_storage_threshold对于一些特殊需求还是不错的。
--比如如果应用中保存的字符串在4000上下,如果使用blob保存,8k的数据块至少浪费50%的空间,而设置
--_scalar_type_lob_storage_threshol=5000,可以很好的规避这些问题。
--当然这这些东西真要在生产系统使用还是要严格测试,谨慎使用!!