[20120608]IOT的第2索引重建.txt

参考链接:
http://richardfoote.wordpress.com/2012/05/15/index-rebuild-does-it-use-the-index-or-the-table-nothing-touches-me/

IOT表是特殊的索引结构,如果第2索引的物理猜失败很多,可以通过rebuild来重建索引,修复物理猜失败.
很明显第2索引重建的一个目的就是修复物理猜失败,这样要获得正确的UROWID,必须扫描IOT组织表,获得正确的逻辑rowid.
但是普通的堆表索引呢?下面看几个例子:

测试环境:

select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

1.测试head表的情况:

create table t as select rownum id, cast(dbms_random.string('x',10) as varchar2(10)) name,lpad('x',100,0) other from dual connect by level
create index i_t_name on t(name);
exec dbms_stats.gather_table_stats(user,'T');
2.做一个10046跟踪看看:
alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
alter index i_t_name rebuild ;
alter session set events '10046 trace name context off';

SQL ID: 8y4va6xg7905s
Plan Hash: 294279316
alter index i_t_name rebuild

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          2          2          0           0
Execute      1      0.35       0.87        315     100047        972           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.36       0.87        317     100049        972           0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 84
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  INDEX BUILD NON UNIQUE I_T_NAME (cr=100172 pr=315 pw=307 time=0 us)(object id 0)
 100000   SORT CREATE INDEX (cr=100008 pr=308 pw=0 time=124167 us)
 100000    INDEX FAST FULL SCAN I_T_NAME (cr=100008 pr=308 pw=0 time=428512 us)(object id 96623)

--可以发现要rebuild index,选择的是INDEX FAST FULL SCAN I_T_NAME,既扫描i_t_name索引.
--应该表比较大,而索引相对小,执行计划选择扫描索引.

3.如果加入online参数呢?

alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
alter index i_t_name rebuild online ;
alter session set events '10046 trace name context off';
SQL ID: 7974hk0xzpwx8
Plan Hash: 2403602364
alter index i_t_name rebuild online
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          1          1          0           0
Execute      1      0.27       0.87       1724       1809       1162           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.27       0.87       1725       1810       1162           0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 84
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  INDEX BUILD NON UNIQUE I_T_NAME (cr=1929 pr=1718 pw=307 time=0 us)(object id 0)
 100000   SORT CREATE INDEX (cr=1700 pr=1716 pw=0 time=155625 us)
 100000    TABLE ACCESS FULL T (cr=1700 pr=1716 pw=0 time=123272 us cost=472 size=1100000 card=100000)

--可以发现如果是rebuild online,对于对表选择的是全表扫描.

4.如果表相对索引很小,在rebuild的时候,会选择cost很低的全表扫描.

drop table t purge;
create table t as select rownum id, cast(dbms_random.string('x',10) as varchar2(10)) name,lpad('x',100,0) other from dual connect by level
create index i_t_name on t(name) pctfree 90;
exec dbms_stats.gather_table_stats(user,'T');

alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
alter index i_t_name rebuild ;
alter session set events '10046 trace name context off';
SQL ID: 8y4va6xg7905s
Plan Hash: 2403602364
alter index i_t_name rebuild

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          2          2          0           0
Execute      1      0.45       6.92       1702       1814       5164           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.45       6.92       1704       1816       5164           0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 84
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  INDEX BUILD NON UNIQUE I_T_NAME (cr=2114 pr=1702 pw=3454 time=0 us)(object id 0)
 100000   SORT CREATE INDEX (cr=1700 pr=1695 pw=0 time=179026 us)
 100000    TABLE ACCESS FULL T (cr=1700 pr=1695 pw=0 time=196289 us cost=472 size=1100000 card=100000)

5.而对于IOT表呢?
很明显前面已经提高rebuild一定要扫描IOT表,这样才能修复物理猜的失败.

create table t_iot (id number constraint t_iot_pk primary key, name varchar2(10), other varchar2(100)) organization index;
insert into t_iot select rownum id, cast(dbms_random.string('x',10) as varchar2(10)) name,lpad('x',100,0) other from dual connect by level
create index i_t_iot_name on t_iot(name) ;
exec dbms_stats.gather_table_stats(user,'t_iot');
alter system flush buffer_cache;
alter session set events '10046 trace name context forever, level 12';
alter index i_t_iot_name rebuild ;
alter session set events '10046 trace name context off';
SQL ID: 7cysaqqva4gy5
Plan Hash: 3369793897
alter index i_t_iot_name rebuild

call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.82       1.43       1594     100078       1090           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.82       1.43       1594     100078       1090           0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 84
Rows     Row Source Operation
-------  ---------------------------------------------------
      1  INDEX BUILD NON UNIQUE I_T_IOT_NAME (cr=100210 pr=1593 pw=390 time=0 us)(object id 0)
 100000   SORT CREATE INDEX (cr=100036 pr=1586 pw=0 time=138489 us)
 100000    INDEX FAST FULL SCAN T_IOT_PK (cr=100036 pr=1586 pw=0 time=479279 us cost=426 size=1100000 card=100000)(object id 96642)

总结:
对比再次看出heap表与IOT的不同,iot的第2索引记录的逻辑rowid,如果iot数据发生变化时,里面记录的逻辑rowid不对,这样物理才失败,在rebuild的时候,要
修复这个问题,仅仅要扫描IOT表.而堆表,索引里面除了保存索引键值外,好保存rowid,这样在重建的时候不需要扫描扫描表.而选择online reuild,这个是一种
特殊情况,允许DML操作,不锁表,要选择全表扫描来rebuild索引.

时间: 2024-10-14 13:35:09

[20120608]IOT的第2索引重建.txt的相关文章

[20121028]IOT的第2索引-NULL的问题.txt

[20121028]IOT的第2索引-NULL的问题.txt IOT表实际上时索引结构,如果第2索引的键值为NULL,会是什么情况呢? 因为第2索引包含主键,而主键是不能为NULL的,这样即使第2索引的键值为NULL,会包括在第2索引中吗? 自己做一些测试验证看看: 1.测试环境: SQL> select * from v$version where rownum BANNER -----------------------------------------------------------

[20130104]关于索引重建的一些问题.txt

[20130104]关于索引重建的一些问题.txt 前一阵子与别人讨论关于索引的问题,实际上许多索引按照现在的观点都不需要重建.除非几种特殊的情况,大量的删除操作,或者删除一部分数据,导致一些索引块不会在被插入等情况,写一些例子来说明情况: 1.建立测试环境: SQL> select * from v$version where rownum BANNER ----------------------------------------------------------------------

[20150203]关于位图索引1.txt

[20150203]关于位图索引1.txt --许多人知道在oltp系统不适合使用位图索引.它的索引的记录结构如下是: 字段0:键值 字段1:开始rowid 字段2:结束rowid 字段3:位图信息,指示那行记录,位图1=>表示存在.位图0=>表示不存在. --但是字段4的位图信息,介绍的资料太少,我自己看了链接http://juliandyke.com/Presentations/BitmapIndexInternals.ppt,做一个简单探究. 1.建立测试环境: SCOTT@test&g

[20150203]关于位图索引2.txt

[20150203]关于位图索引2.txt --许多人知道在oltp系统不适合使用位图索引.它的索引的记录结构如下是: 字段0:键值 字段1:开始rowid 字段2:结束rowid 字段3:位图信息,指示那行记录,位图1=>表示存在.位图0=>表示不存在. --但是字段4的位图信息,介绍的资料太少,我自己看了链接http://juliandyke.com/Presentations/BitmapIndexInternals.ppt,做一个简单探究. 1.建立测试环境: SCOTT@test&g

[20140509]关于索引问题.txt

[20140509]关于索引问题.txt --今天检查生产系统,发现一个奇怪的现象,对应的表和索引基本一样大,自己做一些检查: > @ver BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi > column PCT_INCREASE noprint > column

ORACLE 如何查看索引重建进度情况

   在ORACLE数据库中,如果一个比较大的索引在重建过程中耗费时间比较长,那么怎么查看索引重建耗费的时间,以及完成了多少(比例)了呢,我们可以通过V$SESSION_LONGOPS视图来查看索引重建的时间和进度.   官方文档关于V$SESSION_LONGOPS的介绍如下 V$SESSION_LONGOPS This view displays the status of various operations that run for longer than 6 seconds (in a

[20150205]关于位图索引6.txt

[20150205]关于位图索引6.txt --许多人知道在oltp系统不适合使用位图索引.它的索引的记录结构如下是: 字段0:键值 字段1:开始rowid 字段2:结束rowid 字段3:位图信息,指示那行记录,位图1=>表示存在.位图0=>表示不存在. --昨天主要学习了解了字段3的相关信息,昨晚想起以前itpub的讨论,讲位图索引很容易出现阻塞,主要是如果事务发生在同一个行片, --如果不在同一个行片,就不会出现阻塞,还是通过例子来说明: 1.建立测试环境: SCOTT@test>

[20150205]关于位图索引7.txt

[20150205]关于位图索引7.txt --许多人知道在oltp系统不适合使用位图索引.它的索引的记录结构如下是: 字段0:键值 字段1:开始rowid 字段2:结束rowid 字段3:位图信息,指示那行记录,位图1=>表示存在.位图0=>表示不存在. --但是字段4的位图信息,介绍的资料太少,我自己看了链接http://juliandyke.com/Presentations/BitmapIndexInternals.ppt,做一个简单探究. --前面的blog已经讲解了字段3的位图信息

[20150204]关于位图索引5.txt

[20150204]关于位图索引5.txt --许多人知道在oltp系统不适合使用位图索引.它的索引的记录结构如下是: 字段0:键值 字段1:开始rowid 字段2:结束rowid 字段3:位图信息,指示那行记录,位图1=>表示存在.位图0=>表示不存在. --但是字段4的位图信息,介绍的资料太少,我自己看了链接http://juliandyke.com/Presentations/BitmapIndexInternals.ppt,做一个简单探究. --前面的讲解仅仅在1个数据块的情况,如果开