进行index full scan的时候 oracle定位到索引的root block,然后到branch block(假如有的话),
再定位到第一个leaf block, 然后根据leaf block的双向链表顺序读取。它所读取的块都是有顺序的,
也是经过排序的。(Index full scan reads the index data in the order of the data. ),
而index fast full scan则不同,它是从段头开始,读取包含位图块,root block,所有的branch block,
leaf block,读取的顺序完全有物理存储位置决定,并采取多块读,每次读取db_file_multiblock_read_count
个块。(Index fast full scan reads the index blocks in the physical order of the blocks) .
另外index fast full scan 用多块读的方式来读取数据块, index full scan使用单块读
对index直接rebuild 和 rebuild online 分别会使用什么扫描模式呢 ?
rebuild index 和 rebuild index online 探讨
当表上的dml操作过多以后表上相应的index可能会变得很稀疏不仅浪费了大量的存储空间,同时也会造成性能的下降。这时我们就需要对索引进行重建,对于重建有两种办法一种是先将old index drop,then create the new index,但是这对于大数据量的表是很费时间的而且在create的时候会阻塞表上的操作(除非create的时候带上online选项,这时表上的dml会阻塞索引的建立,只有等表上的dml都commit或rollback后索引才会创建完成),在很多生产环境中这是不允许的.第二种方法就是对index进行rebuild,对于rebuild也有两种选项alter index ind1 rebuild 和 alter index ind1 rebuil online;下面主要讨论下rebuild的两种选项的异同。
1、alter index ind1 rebuild ;
这种方法是对已有的索引进行快速全扫描(如果当索引比表本身还大时也会full table scan的。)然后排序(为什么要排序?这时候Oracle是按照存储的顺序而不是index tree创建的顺序读取,而且索引在存储时是块间有序快内无序的。)再写回索引段,由其原理我们可以得知,这种方法在操作时是不允许对索引进行更改的也就意味着对应的表不能进行dml(查询不受影响,因原index依然可用)操作。从阻塞表上的操作来讲它和drop and create 是一样的,但其速度要快许多因为它扫描的是索引而不是表。当新索引建立后删除旧索引。
2、alter index ind1 rebuild online;
这种方法是对表数据进行全表扫描然后建立新的索引,在这个过程中old index 依然可用,因此它不会阻塞表上的dml操作,但其速度很慢。在建立新索引的过程中如果表上发生了dml操作,这些操作对索引的影响会记录到系统自动创建的JOURNAL TABLE AND INDEX内,等新索引建立完成后JOURNAL TABLE AND INDEX的内容会merge到新索引中,因此rebuild online 也应该在系统不太繁忙的时候进行,不然JOURNAL 表会很大,merge会很费时而merge会锁表对并发有影响。
由1、2过程可知新索引在建立的时候旧索引依然存在索引这两中方法在建立时都会需要更多的空间。
测试过程如下:
22:36:28SQL> alter index text_ind1 rebuild;
索引已更改。
已用时间: 00: 00: 04.20 --才4秒
22:37:05 SQL> alter index text_ind1 rebuild online;
索引已更改。
已用时间: 00: 01: 18.90 --用了一分多钟
22:39:09 SQL> explain plan set statement_id='offline' for
22:39:36 2 alter index text_ind1 rebuild;
已解释。
已用时间: 00: 00: 00.00
22:40:47 SQL> select * from table(dbms_xplan.display('plan_table','offline','serial'));
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| TEXT_IND1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | INDEX FAST FULL SCAN| TEXT_IND1 | | | | --索引扫描
----------------------------------------------------------------------
Note: rule based optimization 已选择11行。
已用时间: 00: 00: 00.01
22:41:05 SQL> explain plan set statement_id='online' for
22:41:26 2 alter index text_ind1 rebuild online;
已解释。
已用时间: 00: 00: 00.01
22:41:29 SQL> select * from table(dbms_xplan.display('plan_table','online','serial'));
----------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
----------------------------------------------------------------------
| 0 | ALTER INDEX STATEMENT | | | | |
| 1 | INDEX BUILD NON UNIQUE| TEXT_IND1 | | | |
| 2 | SORT CREATE INDEX | | | | |
| 3 | TABLE ACCESS FULL | TEST | | | | --全表扫描
----------------------------------------------------------------------
Note: rule based optimization 已选择11行。
已用时间: 00: 00: 00.03
22:41:36 SQL> spool off
在另一个session中:
22:36:36 sql>insert into test select * from test where rownum<2;
已创建 1 行。
22:37:05 sql>insert into test select * from test where rownum<2;
已创建 1 行。
对比执行时间可知rebuild 阻塞了insert操作,而rebuild online 没有。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/35489/viewspace-664442/ ,如需转载,请注明出处,否则将追究法律责任。