rebuild 和rebuild online
通京
2023-12-01
一、什么时候创建索引?
索引多并不意味着性能好,索引对查询有利 对DML是有负担的.
A.一个字段包含一个较大范围的值,也就是说重复率比较小,就是所谓的高基数列
在一个大范围内去找小范围或精确的单个或几个值时 ,
索引非常有效,高基数列适合作索引 ,低基数列不适合作索引
B.一个列包含大量的NULL值
索引是不存NULL值的,那也就意味着这个索引很小,查起来很快
但只限于查明确值
C.频繁在where子句中出现的列 我们要关注是否建立索引
D.大表的外键列,需要建立索引,因为主键值的DML操作会间接的去外键中验证是否在外键列引用
外键列此时没索引, 就要全表扫描, 所以一个主键只有几条记录,外键无索引一个DML可能会几个小时
二、什么时候不创建索引
1.这个列虽然索引效果很好,但是你业务中很少去使用这个列去查询的,考虑不要建索引,以均衡索引的成本.
2.如果该列上返回的结果集大于总结果集的2-4%(看总的数据量和CBO算法来定这只是参考值),谨慎考虑建立索引.
3.表很小时。因为很小表的时候全表访问比索引访问成本还低,有没有索引影响不大 业务初期的时候不创建索引 ,后期有一定的数据量的时候从创建
4.频繁更新的表,其频繁甚至超过查询,慎重考虑建立索引
5.这个索引列使用了函数表达式 需要创建函数索引
SQL> select instance_name ,status from v$instance;
INSTANCE_NAME STATUS
---------------- ------------
ora10g OPEN
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> create table t1 as select * from emp;
Table created.
SQL> create index i_t1_empno on t1(empno); ------普通情况下创建索引,oracle会对基表加share锁,由于share锁和 row-X是不兼容的,也就是说,在建立索引期间,无法对基表进行DML操作。
Index created.
SQL> alter index i_t1_empno rebuild; --------oracle在rebuild时,在创建新索引过程中,并不会删除旧索引,直到新索引rebuild成功。从而可以知道rebuild比删除重建的一个好处是不会影响原有的SQL查询,但也正由于此,用rebuild方式建立索引需要相应表空间的空闲空间是删除重建方式的2倍。
Index altered.
SQL> analyze index i_t1_empno validate structure;
Index analyzed.
SQL> select HEIGHT , BLOCKS , BR_BLKS, LF_BLKS, LF_ROWS , DEL_LF_ROWS from index_stats ;
HEIGHT BLOCKS BR_BLKS LF_BLKS LF_ROWS DEL_LF_ROWS
---------- ---------- ---------- ---------- ---------- -----------
1 8 0 1 14 0
重建只能在没有事务的情况下进行,如果有未提交的事务,就会报错。
SQL> alter index i_t1_empno rebuild;
alter index i_t1_empno rebuild
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified
我们加上online选项。
SQL> alter index i_t1_empno rebuild online;
我们发现会话挂起了,说明在等待资源。我们在另一个会话里查询等待会话的等待事件。
SQL> select event from v$session_wait where sid=159;
EVENT
-----------------------------
enq: TM – contention
SQL> select SID,REQUEST from v$lock where request<>0;
SID REQUEST
---------- ----------
159 4
因为159会话没有获得足够的锁资源而等待。
因为索引重建要求所有要索引的行都要就位,所以必须等待事务结束。索引重建会改变索引的结构,释
放多余的空间,可以改变索引的表空间和索引类型。
rebuild模式下,因为表数据不会产生变化,oracle主要考虑性能问题,把更快扫描完成的段作为数据源,一般索引字段比较多,或者对索引字段的DML操作较多,可能会导致索引比表大,这时oracle就会使用基表作为新索引的数据源进行rebuild了。
而在rebuild online模式下,因为允许DML操作,而表数据变化的同时索引也会跟着变化,为了索引与基表数据的一致性,必须采用基表数据作为数据源,而不能用原索引数据作为数据源。
综上:
1、rebuild会阻塞对基表的DML操作,但不会影响rebuild期间查询对原有索引的使用。
2、rebuild的数据源可能是基表,也可能是原索引。取决于基表和原索引的大小,哪个小,rebuild时就会用那个作为数据源。
3、rebuild online运行用户在索引重建期间执行DML操作。
4、rebuild online的数据源是基表。