我申请这个blog是为了督促自己,把自己平时的一些想法和思考结果保留下来。 本博客所有内容均为原创,如有转载请注明作者和出处

索引重建的数据源

上一篇 / 下一篇  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{2qi fJ o
| 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#\dd@
|   2 |   SORT CREATE INDEX    |                   | 58483 |  3769K|            |          |
C]K1HgxI1D }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,e I9d 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*kuA A0-----------------------------------------------------------------------------------

已选择10行。

看上面这个例子,由于表中只有一列,Oracle在重建索引的时候认识到读取表的代价要比读取索引的代价低,因此选择了全表扫描作为索引重建的数据源。

看来不仅是DML采用CBO优化模式,就是DDL也会根据代价的不同而调整执行计划。

 


TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar