alter index rebuild与alter index rebuild online的区别

本文用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所在的数据文件。而上面两个例子就证明了文章开始时的论断。

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值