oracle索引介绍(图⽂详解)
对于数据库来说,索引是⼀个必选项,但对于现在的各种⼤型数据库来说,索引可以⼤⼤提⾼数据库的性能,以⾄于它变成了数据库不可缺少的⼀部分。
索引分类:
逻辑分类
single column or concatenated 对⼀列或多列建所引
unique or nonunique 唯⼀的和⾮唯⼀的所引,也就是对某⼀列或⼏列的键值(key)是否是唯⼀的。
Function-based 基于某些函数索引,当执⾏某些函数时需要对其进⾏计算,可以将某些函数的计算结果事先保存并加以索引,提⾼效率。
Doman 索引数据库以外的数据,使⽤相对较少
物理分类
B-Tree :normal or reverse key B-Tree索引也是我们传统上常见所理解的索引,它⼜可以分为正常所引
和倒序索引。Bitmap :位图所引,后⾯会细讲
B-Tree 索引
B-Tree index 也是我们传统上常见所理解的索引。B-tree (balance tree)即平衡树,左右两个分⽀相对平衡。
B-Tree index
Root为根节点,branch 为分⽀节点,leaf 到最下⾯⼀层称为叶⼦节点。每个节点表⽰⼀层,当查某⼀数据时先读根节点,再读⽀节点,最后到叶⼦节点。叶⼦节点会存放index entry (索引⼊⼝),每个索引⼊⼝对应⼀条记录。
Index entry 的组成部分:
Indexentry entry header 存放⼀些控制信息。
Key column length 某⼀key的长度
Key column value 某⼀个key 的值
ROWID 指针,具体指向于某⼀个数据
创建索引:
复制代码代码如下:
rows函数的使用方法及实例⽤户登录:
SQL> conn as1/as1
Connected.
创建表:
SQL> create table dex (id int,sex char(1),name char(10));
Table created.
向表中插⼊1000条数据
SQL> begin
for i in 1..1000
loop
insert into dex values(i,'M','chongshi');
end loop;
commit;
end;
/
PL/SQL procedure successfully completed.
查看表记录
SQL> select * from dex;
ID SE NAME
---------- -- --------------------
... . .....
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
rows selected.
创建索引:
SQL> create index dex_idx1 on dex(id);
Index created.
注:对表的第⼀列(id)创建索引。
查看创建的表与索引
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
--------------------------------------------------------------------------------
DEX TABLE
DEX_IDX1 INDEX
索引分离于表,作为⼀个单独的个体存在,除了可以根据单个字段创建索引,也可以根据多列创建索引。Oracle要求创建索引最多不可超过32列。
复制代码代码如下:
SQL> create index dex_index2 on dex(sex,name);
Index created.
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
--------------------------------------------------------------------------------
DEX TABLE
DEX_IDX1 INDEX
DEX_INDEX2 INDEX
这⾥需要理解:
编写⼀本书,只有章节页⾯定好之后再设置⽬录;数据库索引也是⼀样,只有先插⼊好数据,再建⽴索引。那么我们后续对数据库的内容进⾏插⼊、删除,索引也需要随之变化。但索引的修改是由oracle⾃动完成的。
上⾯这张图能更加清晰的描述索引的结构。
跟节点记录0⾄50条数据的位置,分⽀节点进⾏拆分记录0⾄10.......42⾄50,叶⼦节点记录每第数据的
长度和值,并由指针指向具体的数据。
最后⼀层的叶⼦节是双向链接,它们是被有序的链接起来,这样才能快速锁定⼀个数据范围。
如:
复制代码代码如下:
SQL> select * from dex where id>23 and id<32;
ID SE NAME
---------- -- --------------------
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
M chongshi
rows selected.
如上⾯查的列⼦,通过索引的⽅式先到第23条数据,再到第32条数据,这样就能快速的锁定⼀个查的范围,如果每条数据都要从根节点开始查的话,那么效率就会⾮常低下。
位图索引
位图索引主要针对⼤量相同值的列⽽创建。拿全国居民登录⼀第表来说,假设有四个字段:姓名、性别、年龄、和⾝份证号,年龄和性别两个字段会产⽣许多相同的值,性别只有男⼥两种值,年龄,1到120(假设最⼤年龄120岁)个值。那么不管⼀张表有⼏亿条记录,但根据性别字段来区分的话,只有两种取值(男、⼥)。那么位图索引就是根据字段的这个特性所建⽴的⼀种索引。
Bitmap Index
从上图,我们可以看出,⼀个叶⼦节点(⽤不同颜⾊标识)代表⼀个key , start rowid 和 end rowid规定这种类型的检索范围,⼀个叶⼦节点标记⼀个唯⼀的bitmap值。因为⼀个数值类型对应⼀个节点,当时⾏查询时,位图索引通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。
假设存在数据表T,有两个数据列A和B,取值如下,我们看到A和B列中存在相同的数据。
对两个数据列A、B分别建⽴位图索引:idx_t_bita和idx_t_bitb。两个索引对应的存储逻辑结构如下:
Idx_t_bita索引结构,对应的是叶⼦节点:
Idx_t_bitb索引结构,对应的是叶⼦节点:
对查询“select * from t where b=1 and (a='L' or a='M')”
分析:位图索引使⽤⽅⾯,和B*索引有很⼤的不同。B*索引的使⽤,通常是从根节点开始,经过不断的分⽀节点⽐较到最近的符合条件叶⼦节点。通过叶⼦节点上的不断Scan操作,“扫描”出结果集合rowid。
⽽位图索引的⼯作⽅式截然不同。通过不同位图取值直接的位运算(与或),来获取到结果集合向量(计算出的结果)。
针对实例SQL,可以拆分成如下的操作:
1、a='L' or a='M'
a=L:向量:1010
a=M:向量:0001
or操作的结果,就是两个向量的或操作:结果为1011。
2、结合b=1的向量
中间结果向量:1011
B=1:向量:1001
and操作的结果,1001。翻译过来就是第⼀和第四⾏是查询结果。
3、获取到结果rowid
⽬前知道了起始rowid和终⽌rowid,以及第⼀⾏和第四⾏为操作结果。可以通过试算的⽅法获取到结果集合rowid。
位图索引的特点:
1.Bitmap索引的存储空间节省
2.Bitmap索引创建的速度快
3.Bitmap索引允许键值为空
4.Bitmap索引对表记录的⾼效访问
复制代码代码如下:
查看表记录
SQL> select * from dex;
...................
ID SEX NAME
---------- -- --------------------
M chongshi
M chongshi
G chongshi
G chongshi
G chongshi
M chongshi
G chongshi
G chongshi
G chongshi
M chongshi
rows selected.
对于上⾯表来说sex(性别)只有两种值,最适合⽤来创建位图所引
创建索引:
SQL> create bitmap index my_bit_idx on dex(sex);
Index created.
查看创建的所引
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
--------------------------------------------------------------------------------
MY_BIT_IDX INDEX
1、权衡索引个数与DML之间关系,DML也就是插⼊、删除数据操作。
这⾥需要权衡⼀个问题,建⽴索引的⽬的是为了提⾼查询效率的,但建⽴的索引过多,会影响插⼊、删除数据的速度,因为我们修改的表数据,索引也要跟着修改。这⾥需要权衡我们的操作是查询多还是修改多。
2、把索引与对应的表放在不同的表空间。
当读取⼀个表时表与索引是同时进⾏的。如果表与索引和在⼀个表空间⾥就会产⽣资源竞争,放在两个表这空就可并⾏执⾏。
3、最好使⽤⼀样⼤⼩是块。
Oracle默认五块,读⼀次I/O,如果你定义6个块或10个块都需要读取两次I/O。最好是5的整数倍更能提⾼效率。
4、如果⼀个表很⼤,建⽴索引的时间很长,因为建⽴索引也会产⽣⼤量的redo信息,所以在创建索引时可以设置不产⽣或少产⽣redo信息。只要表数据存在,索引失败了⼤不了再建,所以可以不需要产⽣redo信息。
5、建索引的时候应该根据具体的业务SQL来创建,特别是where条件,还有where条件的顺序,尽量将过滤⼤范围的放在后
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论