本文用10046事件来解析alter index rebuild与alter index rebuild online的区别
alter index rebuild online实质上是扫描表而不是扫描现有的索引块来实现索引的重建
alter index rebuild 只扫描现有的索引块来实现索引的重建。
我们可以用10046事件来发现这个现象。
一 先看alter index rebuild:
SQL> conn
请输入用户名: wwf/wwf
已连接。
SQL> drop table wwftest;
表已丢弃。
SQL> create table wwftest as select * from all_objects where rownum < 20000;
表已创建。
SQL> create index ind_wwftest on wwftest(object_id) tablespace idx_ts;
索引已创建。
SQL> alter session set events '10046 trace name context forever, level 12';
会话已更改。
SQL> alter index ind_wwftest rebuild;
索引已更改。
SQL> alter session set events '10046 trace name context off';
会话已更改。
检查导出文件,我们可以在其中发现:
WAIT #1: nam='db file scattered read' ela= 41105 p1=12 p2=11 p3=6
WAIT #1: nam='db file scattered read' ela= 1110 p1=12 p2=17 p3=8
WAIT #1: nam='db file scattered read' ela= 1117 p1=12 p2=25 p3=8
WAIT #1: nam='db file scattered read' ela= 959 p1=12 p2=33 p3=8
WAIT #1: nam='db file scattered read' ela= 955 p1=12 p2=41 p3=8
WAIT #1: nam='db file scattered read' ela= 749 p1=12 p2=49 p3=6
文件12恰好是索引表空间对应的文件编号。
二 我们再看alter index rebuild online
SQL> conn
请输入用户名: wwf/wwf
已连接。
SQL> drop index ind_wwftest;
索引已丢弃。
SQL> create index ind_wwftest on wwftest(object_id) tablespace idx_ts;
索引已创建。
SQL> alter session set events '10046 trace name context forever, level 12';
会话已更改。
SQL> alter index ind_wwftest rebuild online;
索引已更改。
SQL> alter session set events '10046 trace name context off';
会话已更改。
我们看导出文件:
WAIT #1: nam='db file scattered read' ela= 23773 p1=11 p2=34 p3=7
WAIT #1: nam='db file scattered read' ela= 2279 p1=11 p2=41 p3=8
WAIT #1: nam='db file scattered read' ela= 3468 p1=11 p2=49 p3=8
WAIT #1: nam='db file scattered read' ela= 2227 p1=11 p2=57 p3=8
WAIT #1: nam='db file scattered read' ela= 2171 p1=11 p2=65 p3=8
WAIT #1: nam='db file scattered read' ela= 1954 p1=11 p2=73 p3=8
WAIT #1: nam='db file scattered read' ela= 3492 p1=11 p2=81 p3=8
WAIT #1: nam='db file scattered read' ela= 1687 p1=11 p2=89 p3=8
WAIT #1: nam='db file scattered read' ela= 1953 p1=11 p2=97 p3=8
WAIT #1: nam='db file scattered read' ela= 1937 p1=11 p2=105 p3=8
WAIT #1: nam='db file scattered read' ela= 991 p1=11 p2=113 p3=8
WAIT #1: nam='db file scattered read' ela= 2303 p1=11 p2=121 p3=8
WAIT #1: nam='db file scattered read' ela= 1926 p1=11 p2=129 p3=8
WAIT #1: nam='db file scattered read' ela= 1724 p1=11 p2=137 p3=8
WAIT #1: nam='db file scattered read' ela= 1878 p1=11 p2=145 p3=8
WAIT #1: nam='db file scattered read' ela= 3437 p1=11 p2=153 p3=8
WAIT #1: nam='db file scattered read' ela= 81546 p1=11 p2=265 p3=16
WAIT #1: nam='db file scattered read' ela= 4857 p1=11 p2=280 p3=16
WAIT #1: nam='db file scattered read' ela= 3432 p1=11 p2=296 p3=16
WAIT #1: nam='db file scattered read' ela= 3511 p1=11 p2=312 p3=16
WAIT #1: nam='db file scattered read' ela= 2685 p1=11 p2=328 p3=16
WAIT #1: nam='db file scattered read' ela= 4356 p1=11 p2=344 p3=16
WAIT #1: nam='db file scattered read' ela= 2356 p1=11 p2=360 p3=16
WAIT #1: nam='db file scattered read' ela= 3396 p1=11 p2=376 p3=16
WAIT #1: nam='db file sequential read' ela= 347 p1=11 p2=392 p3=1
WAIT #1: nam='db file scattered read' ela= 1924 p1=11 p2=393 p3=16
WAIT #1: nam='db file scattered read' ela= 1051 p1=11 p2=408 p3=8
在本例中,文件11是表wwftest所在的数据文件。而上面两个例子就证明了文章开始时的论断。
分类: ( Oracle管理) :: 评论 (4) :: 静态链接网址 :: 引用 (0)
metalink Note:272762.1关于两者区别的解释 [回复]
Problem:
========
- Online Index rebuild takes a long time.
- ONLINE INDEX REBUILD SCANS THE BASE TABLE AND NOT THE INDEX
Symptoms:
=========
Performance issues while rebuilding very large indexes.
- The offline rebuilds of their index is relatively quick -finishes in 15 minutes.
- Issuing index rebuild ONLINE statement => finishes in about an hour.
- This behavior of ONLINE index rebuilds makes it a non-option for large tables
as it just takes too long to scan the table to rebuild the index. The
offline may not be feasible due to due to the 24/7 nature of the database.
- This may be a loss of functionality for such situations.
- If we attempt to simultaneously ONLINE rebuild the same indexes we may encounter
hanging behavior indefinitely (or more than 6 hours).
DIAGNOSTIC ANALYSIS:
--------------------
We can trace the sessions rebuilding the indexes with 10046 level 12.
Comparing the IO reads for the index-rebuild and the index-rebuild-online
reveals the following:
-ONLINE index rebuilds
It scans the base table and it doesn't scan the blocks of the index.
-OFFLINE index rebuilds
It scans the index for the build operation.
- This behaviour is across all versions.
Cause
Cause/Explanation
=============
When you rebuild index online,
- it will do a full tablescan on the base table.
- At the same time it will maintain a journal table for DML data, which has
changed during this index rebuilding operation.
So it should take longer time, specially if you do lots of DML on the same table,
while rebuilding index online.
On the other hand, while rebuilding the index without online option, Oracle will grab
the index in X-mode and rebuild a new index segment by selecting the data from
the old index. So here we are
- not allowing any DML on the table hence there is no journal table involved
- and it is doing an index scan
Hence it will be pretty fast.
Fix
Solution/Conclusion:
===========
- The ONLINE index rebuild reads the base table, and this is by design.
- Rebuilding index ONLINE is pretty slow.
- Rebuilding index offline is very fast, but it prevents any DML on the base table.
www.wwf.co | 25/08/2005, 22:23
[回复]
赞.
老和尚 | 26/08/2005, 10:03
谢谢老和尚鼓励! [回复]
谢谢!
www.wwf.co | 26/08/2005, 10:29
在index处于unusable状态下,rebuild offline扫描整个表。 [回复]
Note:278600.1 When Does Offline Index Rebuild Refer To Base Table?
Goal
An index rebuilt either Online or Offline.
Online Index Rebuild Features:
+ ALTER INDEX REBUILD ONLINE;
+ DMLs are allowed on the base table
+ It is comparatively Slow
+ Base table is referred for the new index
+ Base table is locked in shared mode and DDLs are not possible
+ Intermediate table stores the data changes in the base table, during the index rebuild to update the new index later
Offline Index Rebuild Features:
+ ALTER INDEX REBUILD; (Default)
+ Does not refer the base table and the base table is exclusively locked
+ New index is created from the old index
+ No DML and DDL possible on the base table
+ Comparatively faster
So, the base table is not referred for data when the index is rebuilt offline.
This article describes this behavior with test cases and depicts a few scenarios when this is violated.
Fix
The test cases considers BTree index being rebuilt online/offline. The results are also same for Bitmap index. For analysis 10046 trace is generated to see if the statement refers the base table for data access. Trace Analyzer is also used to get a clear picture (Note: 224270.1).
Base Table: T5
Index Name: IND5
Test - 1:
=========
Index is rebuilt OFFLINE
alter session set events '10046 trace name context forever, level 12';
alter index ind5 rebuild;
alter session set events '10046 trace name context off';
The trace analyzer output has the following WAIT details:
+ There is no block access from T5
+ IND5 blocks are accessed
Test - 2:
=========
Index is rebuilt ONLINE:
alter session set events '10046 trace name context forever, level 12';
alter index ind5 rebuild online;
alter session set events '10046 trace name context off';
The trace analyzer output has the following WAIT details:
+ T5 blocks are accessed
CONCLUSION
==========
When an index is rebuilt offline there is no FTS on the base table. When index is rebuilt online all the blocks from the base table are accessed.
These conclusions are when we donot make an scenario when the index is unusable and then there
is data load to the base table, and finally the index is rebuilt. Lets see test results from different scenarios when index is unusable.
Test - 3
=========
Index is made unusable. Nodata is load to the base table.Index is rebuilt.
SQL> ALTER INDEX ind5 UNUSABLE;
Index altered.
SQL> select index_name,status from user_indexes where index_name = 'IND5';
INDEX_NAME STATUS
------------------------------ --------
IND5 UNUSABLE
alter session set events '10046 trace name context forever, level 12';
ALTER INDEX ind5 REBUILD;
alter session set events '10046 trace name context off';
SQL> select index_name,status from user_indexes where index_name = 'IND5';
INDEX_NAME STATUS
------------------------------ --------
IND5 VALID
The trace analyzer output has the following WAIT details:
+ There is no block access from T5
+ IND5 blocks are accessed
Test - 4:
=========
Index is made unusable. Data is load to the base table.Then Index is rebuilt OFFLINE.
SQL> ALTER INDEX ind5 UNUSABLE;
Index altered.
SQL> insert into t5 values(55555,'EEEEE');
insert into t5 values(55555,'EEEEE')
*
ERROR at line 1:
ORA-01502: index 'BH.IND5' or partition of such index is in unusable state
Test - 5:
=========
Now lets do some dataload using sqlldr.
Index made unusable / sqlldr dataload to table / rebuild index
load data
infile *
append
into table t5(
a position(1:5),
b position(6:10))
BEGINDATA
55555EEEEE
44444DDDDD
66666FFFFF
sqlldr userid=bh/sh control=test.ctl log=test.log bad=test.bad discard=test.discard skip=0
(skip_unusable_indexes = false -- DEFAULT)
all the three rows are listed in test.bad. NO DATA LOADED
Test - 6:
=========
Index made unusable / sqlldr dataload to table with skip_unusable_indexes=true / rebuild index
SQL> select count(*) from t5;
COUNT(*)
----------
0
SQL> create index ind5 on t5(b) storage(initial 1K next 1K maxextents unlimited pctincrease 0);
Index created.
SQL> select block_id,blocks from dba_extents where segment_name = 'T5';
BLOCK_ID BLOCKS
---------- ----------
5897 130
SQL> select block_id,blocks from dba_extents where segment_name = 'IND5';
BLOCK_ID BLOCKS
---------- ----------
4682 2
SQL> alter index ind5 unusable;
Index altered.
sqlldr userid=bh/sh control=test.ctl log=test.log bad=test.bad discard=test.discard skip_unusable_indexes=true
SQL> select count(*) from t5;
COUNT(*)
----------
154400
DATA GETS LOADED to table. Data doesnot go to index.
SQL> select block_id,blocks from dba_extents where segment_name = 'T5';
BLOCK_ID BLOCKS
---------- ----------
5897 130
4684 130
4814 195
SQL> select block_id,blocks from dba_extents where segment_name = 'IND5';
BLOCK_ID BLOCKS
--------- ----------
4682 2
No new blocks gets added to index.
SQL> select status,index_type from user_indexes where index_name = 'IND5';
STATUS
--------
UNUSABLE
alter session set events '10046 trace name context forever, level 12';
ALTER INDEX ind5 REBUILD;
alter session set events '10046 trace name context off';
SQL> select count(*) from dba_extents where segment_name = 'IND5';
COUNT(*)
----------
9
SQL> select status,index_type from user_indexes where index_name = 'IND5';
STATUS
--------
VALID
From trace analyzer o/p, there is trace that T5 has been referred.
+
CONCLUSION
==========
As documentation says, while REBUILDing an index OFFLINE, the base table is not referred. But there are situations where the base table is accessed similar to an index create, they are:
+ index is made "unusable"
+ data is loaded with sql loader with skip_unusable_indexes = TRUE
+ index is REBUILD OFFLINE
Documentation is not in agreement in this particular case.
There could be one more scenarion I guess:
+ move a table to a different tablespace
+ index becomes unusable
+ we rebuild the index
Basically, when an index is made "unusable", it is normally meant that it will not be used at all (that is drop later) or it has to be drop/create. Here the index being unusable takes more priority than the Offline rebuild of it. An unusable index has to refer the base table while rebuilding.
www.wwf.co | 26/08/2005, 16:28