重建全局分区索引和非分区索引
对表进行任何一种分区级的操作,几乎都会使用所有全局分区索引或非分区索引无法使用。从本质上讲,索引始终必须重建。Oracle11g中的一个内置功能,允许把重建索引作为分区表操作的一部分来执行。使用分区级合并操作的例子,你可以看到,可以在alter table … merge命令中添加更新索引(update indexes)子句,这指示Oracle重建被分区级操作标记为不可用的任何索引。请看下面的例子:
SQL> alter table employees_part merge partitions p2001,pmax into partition pmax update indexes; Table altered. SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO' 2 union 3 select index_name,partition_name,status from user_ind_partitions where index_name in 4 (select index_name from user_indexes where table_name='EMPLOYEES_PART') 5 order by 1,2,3; INDEX_NAME PARTITION_NAME STATUS ------------------------------ ---------------------------------------- -------- EMPLOYEES_PART_PK VALID EMPLOYEES_PART_UK1 MANAGER_100 USABLE EMPLOYEES_PART_UK1 MANAGER_200 USABLE EMPLOYEES_PART_UK1 MANAGER_300 USABLE EMPLOYEES_PART_UK1 MANAGER_400 USABLE EMPLOYEES_PART_UK1 MANAGER_500 USABLE EMPLOYEES_PART_UK1 MANAGER_600 USABLE EMPLOYEES_PART_UK1 MANAGER_700 USABLE EMPLOYEES_PART_UK1 MANAGER_800 USABLE EMPLOYEES_PART_UK1 MANAGER_900 USABLE EMPLOYEES_PART_UK1 MANAGER_MAX USABLE EMPLOYEE_PART_LI P1990 USABLE EMPLOYEE_PART_LI P1991 USABLE EMPLOYEE_PART_LI P1992 USABLE EMPLOYEE_PART_LI P1993 USABLE EMPLOYEE_PART_LI P1994 USABLE EMPLOYEE_PART_LI P1995 USABLE EMPLOYEE_PART_LI P1996 USABLE EMPLOYEE_PART_LI P1997 USABLE EMPLOYEE_PART_LI P1998 USABLE EMPLOYEE_PART_LI P1999 USABLE EMPLOYEE_PART_LI P2000 USABLE EMPLOYEE_PART_LI PMAX USABLE 23 rows selected.
使用update indexes子句重建索引的一个关键优势是,在重建操作过程中索引仍然是在线和可用的。虽然上述例子非常简单,但使用update indexes子句的缺点之一是,由于在分区级别的操作中包装了索引重建操作,在如何重建索引方面,你失去了一定的灵活性。例如,如果你有多个索引需要重建。分别发出命令来重建每个索引的速度可能会更快。要达到这种效果,就可以同时并发地运行多个alter index … rebuild命令。虽然这种方法比较复杂,但哪怕只为了加快速度,这么做可能也是有必要的。
要重建非分区索引,只需要执行alter index … rebuild命令即可。
SQL> alter index employees_part_pk rebuild; Index altered.
此外,对于每个索引,可以选择性地决定使用并行机制,如下面的例子所示:
SQL> alter index employees_part_pk rebuild parallel(degree 4); Index altered. SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO' 2 union 3 select index_name,partition_name,status from user_ind_partitions where index_name in 4 (select index_name from user_indexes where table_name='EMPLOYEES_PART') 5 order by 1,2,3; INDEX_NAME PARTITION_NAME STATUS ------------------------------ ---------------------------------------- -------- EMPLOYEES_PART_PK VALID EMPLOYEES_PART_UK1 MANAGER_100 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_200 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_300 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_400 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_500 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_600 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_700 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_800 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_900 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_MAX UNUSABLE EMPLOYEE_PART_LI P1990 USABLE EMPLOYEE_PART_LI P1991 USABLE EMPLOYEE_PART_LI P1992 USABLE EMPLOYEE_PART_LI P1993 USABLE EMPLOYEE_PART_LI P1994 USABLE EMPLOYEE_PART_LI P1995 USABLE EMPLOYEE_PART_LI P1996 USABLE EMPLOYEE_PART_LI P1997 USABLE EMPLOYEE_PART_LI P1998 USABLE EMPLOYEE_PART_LI P1999 USABLE EMPLOYEE_PART_LI P2000 USABLE EMPLOYEE_PART_LI PMAX USABLE 23 rows selected.
使用这种方法同样需要有足够的判断力和常识。如果需要一次性重建许多索引,同时又想使用并行机制,那么你必须注意到并发操作会有一个缺点。这需要根据具体的环境来作出决定。最初,最好用谨慎的态度开始。可以先慢慢提交少量的操作,以确保并发操作不造成IO或CPU瓶颈,也不造成临时表空间的瓶颈。如果并发操作没有造成这些瓶颈,那么就可以同时运行更多的重建命令。
重建非分区索引还有另一种选择,即简单地删除非分区不可用索引,并使用create index命令重新创建索引。
如果要重建全局分区索引,也有两种选择,既可以删除索引并使用create index命令作为一个整体重新创建索引,也可以逐个分区的重建全局分区索引。请看下面的例子:
SQL> alter index employees_part_uk1 rebuild partition manager_max; Index altered. SQL> select index_name,null partition_name,status from user_indexes where table_name='EMPLOYEES_PART' and partitioned='NO' 2 union 3 select index_name,partition_name,status from user_ind_partitions where index_name in 4 (select index_name from user_indexes where table_name='EMPLOYEES_PART') 5 order by 1,2,3; INDEX_NAME PARTITION_NAME STATUS ------------------------------ ---------------------------------------- -------- EMPLOYEES_PART_PK VALID EMPLOYEES_PART_UK1 MANAGER_100 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_200 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_300 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_400 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_500 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_600 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_700 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_800 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_900 UNUSABLE EMPLOYEES_PART_UK1 MANAGER_MAX USABLE EMPLOYEE_PART_LI P1990 USABLE EMPLOYEE_PART_LI P1991 USABLE EMPLOYEE_PART_LI P1992 USABLE EMPLOYEE_PART_LI P1993 USABLE EMPLOYEE_PART_LI P1994 USABLE EMPLOYEE_PART_LI P1995 USABLE EMPLOYEE_PART_LI P1996 USABLE EMPLOYEE_PART_LI P1997 USABLE EMPLOYEE_PART_LI P1998 USABLE EMPLOYEE_PART_LI P1999 USABLE EMPLOYEE_PART_LI P2000 USABLE EMPLOYEE_PART_LI PMAX USABLE 23 rows selected.
你将需要对每个全局索引分区执行alter index … rebuild命令。
请注意不能把全局分区索引作为一个整体来重建。请看下面的例子:
SQL> alter index employees_part_uk1 rebuild; alter index employees_part_uk1 rebuild * ERROR at line 1: ORA-14086: a partitioned index may not be rebuilt as a whole
正因为如此,当整个全局分区索引被标记为unusable时,删除它并使用create index命令重新创建索引,这样操作起来可能更为简单。