B树索引
主键和唯一性约束字段的B树索引,效率几乎和海量数据没有关系。
键值重复率低的字段比较适合使用B树索引。
位图索引
键值重复率高的字段比较适合使用位图索引。
count、and、or、in这些特定的操作更适合位图索引。
DML操作比较多的表不适合使用位图索引。
复合索引
在where条件中必须带驱动列,复合索引才会使用。
键值重复率低(DISTINCT数量多)的字段放在前面。
用实验说明为什么位图索引不适合OLTP,比较适合OLAP。即:DML操作比较多的表不适合使用位图索引。
首先创建测试表:
SQL> create table t1(id int,name varchar(10),value varchar(10));
表已创建。
SQL> create bitmap index ind_t1_id on t1(id);
索引已创建。
SQL> insert into t1 values(1,'a','aa');
已创建 1 行。
SQL> insert into t1 values(1,'b','bb');
已创建 1 行。
SQL> commit;
提交完成。
SQL> select * from t1;
ID NAME VALUE
---------- ---------- ----------
1 a aa
1 b bb
session1:
SQL> select distinct sid from v$mystat;
SID
----------
140
SQL> update t1 set id = 2 where name = 'a';
已更新 1 行。
session2:
SQL> select distinct sid from v$mystat;
SID
----------
147
SQL> update t1 set id = 2 where name = 'b';
阻塞信息:
SQL> select * from v$lock where sid in(140,147) order by type;
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
288F60DC 288F60F4 147 TM 55628 0 3 0 111 0
288F6030 288F6048 140 TM 55628 0 3 0 270 0
28945B40 28945B64 147 TX 655404 533 6 0 111 0
28939F60 28939F84 140 TX 589829 616 6 0 270 1
294344A8 294344BC 147 TX 589829 616 0 4 111 0
SQL> select sid,status,last_call_et,blocking_session from v$session where sid in(140,147);
SID STATUS LAST_CALL_ET BLOCKING_SESSION
---------- -------- ------------ ----------------
140 INACTIVE 285
147 ACTIVE 126 140
可以看见140阻塞了147。尽管他们修改的不是同一列。
注意:这里不仅仅是根据name=’a’去修改会阻塞其他会话,如果根据value = ‘aa’或者name = ‘a’ and value = ‘aa’来修改操作,也是同样会阻塞的!!! 因为都是改的id的值,而Index就是建在id上面的。但是如果不是改id列,而是改name或者value列就不存在阻塞的情况!!!
如果使用B树索引,就不存在阻塞情况了。创建同样的t2表,只是索引不一样
SQL> create table t2 as select * from t1;
表已创建。
SQL> select * from t2;
ID NAME VALUE
---------- ---------- ----------
2 a aa
2 b bb
SQL> create index ind_t2_id on t2(id);
索引已创建。
session1:
SQL> select distinct sid from v$mystat;
SID
----------
140
SQL> update t2 set id = 1 where name = 'a';
已更新 1 行。
session2:
SQL> select distinct sid from v$mystat;
SID
----------
147
SQL> update t2 set id = 1 where name = 'b';
已更新 1 行。
可以看见,各自都可以修改,不存在阻塞现象!