原由:
今天在rename表时,特别是表中包含主键索引和唯一索引时也需要将constraint进行rename;
否则在重建回原始表的主键名称时将报错;
类似如下:
*
ERROR at line 1:
ORA-02264: name already used by an existing constraint
后面特地的留意下unique索引情况,一个有兴趣事情发生;
SQL> create table test6 as select object_id,object_name from dba_objects;
Table created.
SQL> create table test6u nologging as select * from test6;
Table created.
SQL> create unique index uni_test6 on test6(object_id);
Index created.
SQL> alter table test6u add constraint uni_test7 unique (object_id);
Table altered.
---在表中dba_constraint查询约束内容
select constraint_name,table_name,constraint_type from dba_constraints
where owner='AIKI2'
and table_name in ('TEST6','TEST6U')
/
CONSTRAINT_NAME TABLE_NAME C
------------------------------ ------------------------------ -
UNI_TEST6U TEST6U U
发现只有test6u包含,而test6没有内容;
接着我们检查执行计划是否有变化
SQL> exec dbms_stats.gather_table_stats(user,'TEST6',cascade=>true);
PL/SQL procedure successfully completed.
SQL> exec dbms_stats.gather_table_stats(user,'TEST6U',cascade=>true);
PL/SQL procedure successfully completed.
SQL> set autotrace ON EXPLAIN STATISTICS
SQL> set linesize 150
SQL> l
1* select * from test6 where object_id=7979
SQL> /
OBJECT_ID OBJECT_NAME
---------- ------------------------------
7979 ODCIINDEXINFOFLAGSDUMP
Execution Plan
----------------------------------------------------------
Plan hash value: 2651143101
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST6 | 1 | 29 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | UNI_TEST6 | 1 | | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=7979)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
492 bytes sent via SQL*Net to client
513 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
SQL> l
1* select * from test6u where object_id=7979
SQL> /
SQL> /
OBJECT_ID OBJECT_NAME
---------- ------------------------------
7979 ODCIINDEXINFOFLAGSDUMP
Execution Plan
----------------------------------------------------------
Plan hash value: 3556035271
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST6U | 1 | 29 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | UNI_TEST6U | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"=7979)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
3 consistent gets
0 physical reads
0 redo size
492 bytes sent via SQL*Net to client
513 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
可以看到执行计划并未有什么不同,那为什么会有这样的差异呢在dba_constraints,有什么用呢?
我们找到administrator文档里有这么一段话
Efficient Use of Integrity Constraints: A Procedure
Using integrity constraint states in the following order can ensure the best benefits:
1. Disable state.
2. Perform the operation (load, export, import).
3. Enable novalidate state.
4. Enable state.
Some benefits of using constraints in this order are:
■ No locks are held.
■ All constraints can go to enable state concurrently.
■ Constraint enabling is done in parallel.
■ Concurrent activity on table is permitted.
大意就是指好处有:
不会持有锁,可以开并行操作
1* select /*+ parallel(t,2) */* from test6u t where object_id=2878
SQL> /
OBJECT_ID OBJECT_NAME
---------- ------------------------------
2878 V_$CPOOL_CC_STATS
Execution Plan
----------------------------------------------------------
Plan hash value: 3556035271
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST6U | 1 | 29 | 2 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | UNI_TEST6U | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------
以上我们看到虽然采用了并行的hint但执行计划并未显示并行操作;
alter table test6u disable constraint uni_test6u;
SQL> l
1* alter table test6u disable constraint uni_test6u
SQL> select /*+ parallel(t,2) */* from test6u t where object_id=2878
2 /
OBJECT_ID OBJECT_NAME
---------- ------------------------------
2878 V_$CPOOL_CC_STATS
Execution Plan
----------------------------------------------------------
Plan hash value: 2220473316
--------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 55 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 1 | 29 | 55 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | PX BLOCK ITERATOR | | 1 | 29 | 55 (0)| 00:00:01 | Q1,00 | PCWC | |
|* 4 | TABLE ACCESS FULL| TEST6U | 1 | 29 | 55 (0)| 00:00:01 | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------
我们可以看到并行计划已经出现了;