这几天在测试环境部署一个适合多种操作系统多种数据库多实例的监控脚本的时候,在一台测试库上监控到一个索引失效,于是根据提示尝试online rebuild
alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics; SQL> alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics; alter index NINGOO.IDX_TEST_KPI_NAME rebuild online compute statistics * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-01450: maximum key length (3215) exceeded
看了下索引是创建在一个varchar2(4000)的列上的:
SQL> select table_name,column_name,column_length from all_ind_columns where index_name='IDX_TEST_KPI_NAME'; TABLE_NAME COLUMN_NAME COLUMN_LENGTH --------------- ---------------------- ------------- TEST KPI_NAME 4000
我们知道一个index key不能跨多个block,所以key的长度有限制的。但是索引既然创建成功,这个要求肯定是满足的。实际测试下,对于8K的block,这个限制应该是6398字节。
SQL> create table test1(a varchar2(4000),b varchar2(4000)); Table created. SQL> create index ix_test1 on test1(a,b); create index ix_test1 on test1(a,b) * ERROR at line 1: ORA-01450: maximum key length (6398) exceeded
那为什么4000字节的key在online rebuild的时候会有问题呢?而创建和正常rebuild操作都是正常的。
SQL> create index ix_test1 on test1(a); Index created. SQL> alter index ix_test1 rebuild online; alter index ix_test1 rebuild online * ERROR at line 1: ORA-00604: error occurred at recursive SQL level 1 ORA-01450: maximum key length (3215) exceeded SQL> alter index ix_test1 rebuild; Index altered.
原因在于IOT表的一些限制,我们可以创建一个IOT表验证一下:
SQL> create table test_iot1(a varchar2(4000),b varchar2(4000), 2 constraint iot1_pk primary key(a,b)) 3 organization index; create table test_iot1(a varchar2(4000),b varchar2(4000), * ERROR at line 1: ORA-01450: maximum key length (3215) exceeded
Online rebuild的过程中需要创建一个临时的IOT表,所以online rebuild的index 的key的长度限制就被大大缩短了。这一点在我们设计系统的索引的时候要特别注意,如果前期设计的索引超过了IOT index key的长度限制,则后期的维护成本会更高,因为无法online rebuild,则rebuild的时候就会锁表导致业务受到较长时间的中断。
当然,实际业务场景中,在varchar2(4000)列上创建索引并不常见,如果真的需要,也可以考虑只创建部分前缀的函数索引,但这需要业务的SQL也做相应修改,这一点上,PostgreSQL直接支持的前缀索引就要灵活得多。
SQL> create index ix_test1_2 on test1(substr(a,1,100)); Index created. SQL> alter index ix_test1_2 rebuild online; Index altered.
对于这个问题,旺旺同学和Jonathan Lewis同学很早就有描述,只是没碰到一般很少碰到key这么长的索引而不容易注意到,再次记录下备忘。
您可能也喜欢: | ||||
ORA-00494与Oracle10.2.0.4 |
关于Oracle Companion CD |
DBA备忘录:Online rebuild index遭遇ORA-08104 |
Oracle Price Lists |
Oracle11gR1 for Linux可以下载了 |
无觅 |