ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 索引创建和重建对键值的限制

索引创建和重建对键值的限制

原创 Linux操作系统 作者:yangtingkun 时间:2009-07-06 23:24:18 0 删除 编辑

简单描述创建和重建索引的过程对索引键值大小的要求。

 

 

索引和表的存储结构不同,由于索引要根据索引键值进行排序,因此要求索引的键值必须能够放到一个BLOCK中。所以根据数据块大小的不同,对键值的大小限制也不同。

一般来说建立索引的时候,索引键值的最大值一般在DB_BLOCK_SIZE3/4左右,看一个DB_BLOCK_SIZE8K的例子:

SQL> SHOW PARAMETER DB_BLOCK_SIZE

NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------------------------
db_block_size                        integer     8192
SQL> CREATE TABLE T_CHAR
  2  (C1 CHAR(2000),
  3  C2 CHAR(2000),
  4  C3 CHAR(2000),
  5  C4 CHAR(2000));

表已创建。

SQL> CREATE INDEX IND_T_CHAR_1 ON T_CHAR(C1, C2, C3);

索引已创建。

SQL> CREATE INDEX IND_T_CHAR_2 ON T_CHAR(C1, C2, C3, C4);
CREATE INDEX IND_T_CHAR_2 ON T_CHAR(C1, C2, C3, C4)
                             *
1 行出现错误:
ORA-01450:
超出最大的关键字长度 (6398)

而这时创建索引的限制,对于ONLINE REBUILD方式,由于Oracle需要在同一个BLOCK中保存至少两个索引键值,因此索引键值的最大限制,只有创建时的一半:

SQL> ALTER INDEX IND_T_CHAR_1 REBUILD ONLINE;
ALTER INDEX IND_T_CHAR_1 REBUILD ONLINE
*
1 行出现错误:
ORA-00604:
递归 SQL 级别 1 出现错误
ORA-01450:
超出最大的关键字长度 (3215)


SQL> ALTER INDEX IND_T_CHAR_1 REBUILD;

索引已更改。

可以看到,普通的REBUILD则没有这个限制。

SQL> show parameter db_block_size

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_block_size                        integer     16384
SQL> create table t_varchar2
  2  (c1 varchar2(4000),
  3  c2 varchar2(4000),
  4  c3 varchar2(4000),
  5  c4 varchar2(4000));

Table created.

SQL> create index ind_t_varchar2_1 on t_varchar2(c1, c2, c3);

Index created.

SQL> create index ind_t_varchar2_2 on t_varchar2(c1, c2, c3, c4);
create index ind_t_varchar2_2 on t_varchar2(c1, c2, c3, c4)
                                 *
ERROR at line 1:
ORA-01450: maximum key length (12958) exceeded


SQL> alter index ind_t_varchar2_1 rebuild online;
alter index ind_t_varchar2_1 rebuild online
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-01450: maximum key length (3800) exceeded

这是DB_BLOCK_SIZE16K的例子,可以看到创建索引的最大键值增加了一倍还多,而ONLINE REBUILD的键值限制却没有多大的增长。

最后看看32K的情况:

SQL> show parameter db_block_size

NAME                                 TYPE                   VALUE
------------------------------------ ---------------------- ------------------------------
db_block_size                        integer                32768
SQL> create table t_var   
  2  (c1 varchar2(4000),
  3  c2 varchar2(4000),
  4  c3 varchar2(4000),
  5  c4 varchar2(4000),
  6  c5 varchar2(4000),
  7  c6 varchar2(4000),
  8  c7 varchar2(4000),
  9  c8 varchar2(4000));

表已创建。

SQL> create index ind_t_var_1 on t_var(c1, c2, c3, c4, c5, c6, c7);
create index ind_t_var_1 on t_var(c1, c2, c3, c4, c5, c6, c7)
                            *
1 行出现错误:
ORA-01450:
超出最大的关键字长度 (26054)


SQL> create index ind_t_var_1 on t_var(c1, c2, c3, c4, c5, c6);

索引已创建。

SQL> alter index ind_t_var_1 rebuild online;
alter index ind_t_var_1 rebuild online
*
1 行出现错误:
ORA-00604:
递归 SQL 级别 1 出现错误
ORA-01450:
超出最大的关键字长度 (3800)

可以看到,ONLINE REBUILD所允许的最大键值就是3800,而CREATE INDEX所允许的最大键值又增加了一倍。从这一点上看,ONLINE REBUILD的限制还是很严的,如果在VARCHAR2(4000)列上建立索引,则意味着这个索引无法进行ONLINE REBUILD。这也从另一个角度说明,定义列的长度时,应该根据具体的需要,而不是随便就定义成最大值。这样即使字段中存储的值没有那么长,但是由于列的定义长度超过限制,也会使得ONLINE REBUILD的操作无法执行。

而且对于8KDB_BLOCK_SIZEONLINE REBUILD的键值最大为3215,如果DB_BLOCK_SIZE4K,甚至是2K,则ONLINE REBUILD的键值限制还会缩小1倍或2倍。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-608464/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10405167