a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 125|回复: 1

[考试辅导] Oracle应用技术:oracle中的不可用索引

[复制链接]
发表于 2012-8-4 14:06:19 | 显示全部楼层 |阅读模式
本文并不是要声名若何把索引标识表记标帜为不成用;. q& H7 Q. \+ u) j2 ?' C
  create index temp_jp_idx on temp_jp(col1 desc);
* S3 m% M$ A' W. q! o! o7 j+ v  那RowID又是什么呢?一个RowID就是用来标识表一一行的伪列,代表了这一行在表中的物理位置。在Oracle 9i往后的版本中,RowID的名目均为扩展RowID名目,如
回复

使用道具 举报

 楼主| 发表于 2012-8-4 14:06:20 | 显示全部楼层

Oracle应用技术:oracle中的不可用索引

</p> select dbms_rowid.rowid_object(rowid) "object", dbms_rowid.rowid_relative_fno(rowid) "file", dbms_rowid.rowid_block_number(rowid) "block", dbms_rowid.rowid_row_number(rowid) "row" from temp_jp/object file block row--------- ---------- ---------- ----------220848 12 12172 0220848 12 12172 1220848 12 12172 2+ `+ W" Z9 m7 B' f6 ?( W
  执行完move呼吁后,Oracle为该表指定了一个新的object_id。属于users2表空间的文件号为12。当前的块ID为12172。而行号还连结和原本一样。Move呼吁改变了表的位置,但没有改变表熟行的枚举挨次。接下来,我们还可以用新的object_id来查找该对象的具体信息。
  y+ `1 z/ i: [2 p7 G  M( D  select object_id,owner, object_name, object_type,created from dba_objects where object_id = 220848;
, E$ r" X8 Q  q8 ?( c9 A  no rows selected
7 {. o' w* s! {  年夜执行move呼吁后的新RowID获得了object_id没有检索到该对象的具体信息。相反,年夜dba_objects视图看该表的对象ID默示为执行move呼吁前的旧object_id。/ h! g5 c" [. t) k
  select object_id,owner, object_name, object_type,created from dba_objectswhere object_name = ‘TEMP_JP‘;OBJECT_ID OWNER OBJECT_NAME OBJECT_TYPE CREATED--------- ------ --------------- ------------------- ---------220845 SCOTT TEMP_JP TABLE 30-MAR-08
6 t+ @: z8 g* G) \  这可能是Oracle数据库的一个裂痕。我们来查找一下在曩昔一小时内建树的对象:& F7 _+ m9 q9 o
  select object_id,owner,object_name,object_type,created from dba_objects where createdtrunc(sysdate) -1/24;OBJECT_ID OWNER OBJECT_NAME OBJECT_TYPE CREATED--------- ------ --------------- ------------------- ---------220846 SCOTT TEMP_JP_IDX INDEX 30-MAR-08220845 SCOTT TEMP_JP TABLE 30-MAR-08220847 SCOTT TEMP_ROWIDS_JP TABLE 30-MAR-08select object_id, owner, object_name, object_type, created from dba_objects where object_id in (select max(object_id) from dba_objects);OBJECT_ID OWNER OBJECT_NAME OBJECT_TYPE CREATED--------- ------- ------------- ------------------- ---------220847 SCOTT TEMP_ROWIDS_JP TABLE 30-MAR-08
4 q" D4 e3 F+ U( f  用新的RowID来发芽表temp_jp:* R* i4 |, C  V% q/ |
  select * from temp_jp where rowid = ‘AAA16wAAMAAAC+MAAB‘; COL1 COL2---------- -------------------- 3 SITA
; F2 V: S2 T8 S3 Y1 D$ r# R8 ?  我们用新RowID能够年夜该表发芽到数据。可是,年夜新RowID获得的objectid并不能检索到对象的具体信息。年夜这点看来,Oracle并没有使用年夜今朝的RowID获得的objectid来检索该表的数据,而是使用fileid、blockid和行号来访谒表数据。# q5 t1 E$ L6 F) Y& B
  那么让我们来看看执行完move呼吁后表temp_jp的索引状况。. o+ \3 P5 A+ K" X4 C
  select index_name, status from dba_indexes where table_name=‘TEMP_JP‘;INDEX_NAME STATUS------------------------------ --------TEMP_JP_IDX UNUSABLEset autot on expselect * from temp_jp where col1=3; COL1 COL2---------- -------------------- 3 SITAExecution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=25) 1 0 TABLE ACCESS (FULL) OF ‘TEMP_JP‘ (TABLE) (Cost=2 Card=1 Bytes=25)  ?* u# v2 H  V5 k
  因为表temp_jp已有的索引无法使用,我们先对该表进行了一次全表扫描。正如你所想到的,表temp_jp的索引仍然存储着无效的RowID。此刻,让我们来看看我们用旧的RowID能不能检索到数据。
' Q5 w& l) k5 g+ t8 d' V( _9 y  SQL select * from temp_jp where rowid = ‘AAA16tAAEAAAADoAAB‘;select * from temp_jp where rowid = ‘AAA16tAAEAAAADoAAB‘ *ERROR at line 1:ORA-01410: invalid ROWID
" M+ q- @% D% u+ x  P. e" U* D  旧的RowID不再指向该表各行的正确物理位置。而索引temp_jp_idx仍保留着执行move呼吁前旧的无效RowID,所以,Oracle把这些索引标识表记标帜为不成用。不外,我们仍是可以用新的RowID来访谒该表的数据。
2 I, w+ [" @% w2 a$ r  select * from temp_jp where rowid = ‘AAA16wAAMAAAC+MAAB‘; COL1 COL2---------- -------------------- 3 SITA7 v, Y9 l2 l& j
  让我们来斗劲一下执行move呼吁前后表temp_jp的RowID有什么分歧。5 A2 _/ p- z. Z5 `9 I( }
  select a.col1, a.before_move_rowid,b.rowid after_move_rowidfrom temp_rowids_jp a, temp_jp b where a.col1 = b.col1; COL1 BEFORE_MOVE_ROWID AFTER_MOVE_ROWID--------- ------------------ ------------------ 1 AAA16tAAEAAAADoAAA AAA16wAAMAAAC+MAAA 3 AAA16tAAEAAAADoAAB AAA16wAAMAAAC+MAAB 2 AAA16tAAEAAAADoAAC AAA16wAAMAAAC+MAAC
1 _% M2 @4 E2 Y$ q5 c* `  X  o# P  正如之前所说的,在执行了move呼吁之后,该表转移到了此吐矣闽表空间,而objectid、fileid和blockid都已经发生了转变。因为表内的数据在表移动的过程中并没有发生改变,所以行号仍保留原样。. _  G& X. ~3 K  w5 z
  为了修复不成用索引,用新的正确的RowID来年夜头生成temp_jp_idx索引即可8 |- ?/ x3 I( K( T' |$ b+ v( {' A
  alter index temp_jp_idx rebuild online;select index_name, status from dba_indexes where table_name=‘TEMP_JP‘;INDEX_NAME STATUS------------------------------ --------TEMP_JP_IDX VALIDAfter rebuilding the unusable index, the index is validated.set autot on expselect * from temp_jp where col1=3; COL1 COL2 ---------- -------------------- 3 SITA Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=25) 1 0 TABLE ACCESS (BY INDEX ROWID) OF ‘TEMP_JP‘ (TABLE) (Cost=2 Card=1 Bytes=25) 2 1 INDEX (RANGE SCAN) OF ‘TEMP_JP_IDX‘ (INDEX) (Cost=1 Card =1)' V% q4 U+ f  _1 N
  年夜头生成索引后,就可以使用该索引来对表temp_jp进行select发芽了。5 b! W, z' T& @/ k. M
  记住,当你要移动一个表时,该表的索引会被标识表记标帜为不成用,但经由过程年夜头生成指令来将索引转移到新的物理位置时,索引就可以恢复可用性了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-5 19:41 , Processed in 0.404893 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表