索引重建的数据源
上一篇 / 下一篇 2008-03-16 22:34:27 / 个人分类:ORACLE
以前一直认为,索引重建的数据源就是索引本身,直到一次同事的测试时发现了这个问题,才纠正了我这个错误。
一般情况下,索引的重建仍然会尝试读取索引:
SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS;
表已创建。
SQL> CREATE INDEX IND_T_OBJECT_NAME ON T(OBJECT_NAME);
索引已创建。
SQL> EXPLAIN PLAN FOR ALTER INDEX IND_T_OBJECT_NAME REBUILD;
已解释。
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUTITPUB个人空间5S1S%U:T4DE
-------------------------------------------------------------------------------------------
;^:^"e&w.sc)mbnr0Plan hash value: 1721975976
--------------------------------------------------------------------------------------------ITPUB个人空间Hs {2qifJo
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |ITPUB个人空间V:IMl
VO(R~K+|i
--------------------------------------------------------------------------------------------ITPUB个人空间;{l-]MYzM(pF/U5T
| 0 | ALTER INDEX STATEMENT | | 58483 | 3769K| 161 (2)| 00:00:02 |ITPUB个人空间:me4D#Tu4M*a!E|_
| 1 | INDEX BUILD NON UNIQUE| IND_T_OBJECT_NAME | | | | |ITPUB个人空间 \/uc'k
z}
| 2 | SORT CREATE INDEX | | 58483 | 3769K| | |
!M*R^4i5_NWj0| 3 | INDEX FAST FULL SCAN| IND_T_OBJECT_NAME | | | | |ITPUB个人空间X7dn.E,|F0b?
--------------------------------------------------------------------------------------------
已选择10行。
除非在重建索引时指定ONLINE参数:
SQL> EXPLAIN PLAN FOR ALTER INDEX IND_T_OBJECT_NAME REBUILD ONLINE;
已解释。
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUT
U
hq?y{0------------------------------------------------------------------------------------------ITPUB个人空间`z#B;N.d^0{ D
Plan hash value: 2895142991
--------------------------------------------------------------------------------------------ITPUB个人空间b yx&mB
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |ITPUB个人空间n"p&]BV5[(g^;P
--------------------------------------------------------------------------------------------ITPUB个人空间4u$O]C8?
| 0 | ALTER INDEX STATEMENT | | 58483 | 3769K| 161 (2)| 00:00:02 |
p5U X[5@7up.Bh6T3{0| 1 | INDEX BUILD NON UNIQUE| IND_T_OBJECT_NAME | | | | |ITPUB个人空间_N(jm,yC#\d d@
| 2 | SORT CREATE INDEX | | 58483 | 3769K| | |
C]K1Hgx I1D
}0| 3 | TABLE ACCESS FULL | T | 58483 | 3769K| 161 (2)| 00:00:02 |
#b+s6sz F0--------------------------------------------------------------------------------------------
已选择10行。
ONLINE模式采用读取表的方式是为了减少REBUILD索引时的锁表时间。
而通过同事的例子发现,Oracle选择索引并不是固定的,而是经过CBO判断后,认为索引扫描的效率更高。
SQL> CREATE TABLE T (ID NUMBER);
表已创建。
SQL> INSERT INTO T SELECT ROWNUM FROM DBA_OBJECTS;
已创建50633行。
SQL> COMMIT;
提交完成。
SQL> CREATE INDEX IND_T_ID ON T(ID);
索引已创建。
SQL> EXPLAIN PLAN FOR ALTER INDEX IND_T_ID REBUILD;
已解释。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T', CASCADE => TRUE)
PL/SQL过程已成功完成。
SQL> EXPLAIN PLAN FOR ALTER INDEX IND_T_ID REBUILD;
已解释。
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
PLAN_TABLE_OUTPUT
^9h(nC0O:e"aJ0--------------------------------------------------------------------------------------ITPUB个人空间$x/GWvb%PAp5f*T7T
Plan hash value: 3865827442
-----------------------------------------------------------------------------------ITPUB个人空间Wue\S3wi.X u
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |ITPUB个人空间9M,eI9d Q/[bfp
-----------------------------------------------------------------------------------
2V5{W;Mm,?0| 0 | ALTER INDEX STATEMENT | | 50633 | 197K| 20 (5)| 00:00:01 |ITPUB个人空间b F5n(s`m0O)A
| 1 | INDEX BUILD NON UNIQUE| IND_T_ID | | | | |ITPUB个人空间+u e.yX[;uy
| 2 | SORT CREATE INDEX | | 50633 | 197K| | |ITPUB个人空间6y8X6c t0JL]S
| 3 | TABLE ACCESS FULL | T | 50633 | 197K| 20 (5)| 00:00:01 |
.z8p~5W*d*kuAA0-----------------------------------------------------------------------------------
已选择10行。
看上面这个例子,由于表中只有一列,Oracle在重建索引的时候认识到读取表的代价要比读取索引的代价低,因此选择了全表扫描作为索引重建的数据源。
看来不仅是DML采用CBO优化模式,就是DDL也会根据代价的不同而调整执行计划。
导入论坛 引用链接 收藏 分享给好友 推荐到圈子 管理 举报
TAG: