数据库对象(索引)

索引:
数据库中对象的一种,它记录了索引列中的数据以及对应的物理位置-ROWID。 --每一行数据对应唯一标识符,记录物理位置。
索引建立时会获取指定列的数据,及其对应的ROWID,并自动地按照某种规则进行排序,索引与表是完全不同的两种对象,两者只是在使用上会有所关联。

数据库检索数据的方式:
全盘扫描:按照条件在对应数据列从第一条数据检索到最后一条数据,一旦条件在某条数据上成立,就将对应的ROWID取出,直到检索到最后一条,然后按照ROWID去对应的物理位置获取整行数据。
索引扫描:按照条件在对应索引列从大概位置开始检索,检索到最后一条符合条件的数据即停止检索,符合条件的数据获取对应的ROWID,最后按照ROWID去对应的物理位置获取整行数据。
除全盘扫描和索引扫描外,还有一种最快的检索方式,就是使用ROWID直接进行扫描,但ROWID的获取需要依赖至少一次查询,所以这种检索方式一般不在考虑范围之内。
而全盘扫描与索引扫描二者相比较,一般情况下索引扫描的速度要高于全盘扫描,所以建立有效的索引是程序运行中提高查询效率的的有效方法。
–select优化

为何索引扫描的效率会高于全盘扫描?
因为索引在建立时不仅会获取索引列的数据和对应的ROWID,还会对数据进行排序,检索数据时就不必遍历所有数据,自然能够提高查询的效率。
其实索引扫描本质上是牺牲了DML语句的操作效率来换取更高的查询效率,若表中建立了索引,在维护该表数据时,会因数据的改变而使索引重新进行排序,这就导致DML的操作时间增加。不过相比于复杂的查询逻辑引起的查询效率降低,绝大多数情况下更能接受DML的效率降低。
另外有些程序中会在DML操作前先将索引置为失效,等DML操作结束后再重新激活索引。

索引的分类:
一、按存储形式(即索引中存储的内容不同)
1)B-TREE索引(索引列原始数据+ROWID)
2)位图索引(位图+ROWID)
3)反向键索引(索引列原始数据的反向存储+ROWID)
4)基于函数的索引(将索引列原始数据经函数处理后存储+ROWID)

索引的命名规范:IND_TBNAME_COLNAME

1.B-TREE索引 BALANCE-TREE
(ORACLE的默认索引类型,工作中最常见、使用范围最广的索引)
语法:
CREATE INDEX IND_NAME ON TB_NAME(COL_NAME);
适用场景:列基数比较大的时候使用(行业、身高)
列基数:该列不重复数据的个数 COUNT(DISTINCT COL)

根块:索引的顶级块,指向下一节点
分支块:包含下一节点的信息,指向下一分支块或者是叶块
叶块:存放索引的入口数据

2.位图索引 (位图+ROWID)
说明:位图索引在创建时,会扫描整张表,为索引列的每个取值建立一个不重复的位图(BITMAP)来描述该取值
语法:CREATE BITMAP INDEX IND_NAME ON TB_NAME(COL_NAME);
适用场景:列基数比较小的时候使用(性别、婚姻状况)

3.反向键索引(简称:反向索引)
说明:可以视作一种特殊的B-TREE索引,存储索引列的反向值
背景:为防止B-TREE索引在某叶上数据量占比过高而使用的一种索引
语法:
CREATE INDEX IND_NAME ON TB_NAME(COL_NAME) REVERSE;
适用场景:原始数据分支不明显但反向数据分支明显的列(身高:集中在一米七一米八)

4.基于函数的索引
说明:可以视作一种特殊的B-TREE索引,存储函数处理后的数据
背景:在某个字段上以原值建立了索引,但是在筛选时在该字段上经常加函数,导致索引无法生效
语法:
CREATE INDEX IND_NAME ON TB_NAME(FUNCTION(COL_NAME));
适用场景:对某列进行筛选时经常需要配合函数使用(例如查找姓名中的首字母)

二、按唯一性(索引列中的数据是否有重复值)
1.唯一索引 --索引列中不可能出现重复值
语法:
CREATE UNIQUE INDEX IND_NAME ON TB_NAME(COL_NAME);
注意点:
1)B-TREE索引可以建立唯一索引,位图索引不能建立唯一索引
2)如果在某列上建立了唯一约束或主键约束,ORACLE会自动在该列上建立一个同名的唯一索引
主键:唯一 非空

2.非唯一索引 --索引列中可能出现重复值
语法:CREATE INDEX IND_NAME ON TB_NAME(COL_NAME);

三、按列的个数(索引覆盖的列的个数)
1.单列索引 --基于一个列建立的索引
语法:
CREATE INDEX IND_NAME ON TB_NAME(COL_NAME);
2.复合索引(也称为联合索引) --基于两个或两个以上列建立的索引
CREATE INDEX IND_NAME ON TB_NAME(COL_NAME1,COL_NAME2…);
用法:先用第一个字段,再写第二个字段

思考:
1.为什么不建议在WHERE筛选中出现隐式转换?
2.索引是越多越好吗?

索引建立或使用的规则与建议
1.如果对某大表进行筛选时,某列或某几列频繁出现在WHERE子句中,并且检索出的数据低于总行数的15%(50%),应考虑在这些列上建立索引。
2.如果对某大表进行排序时,某列或某几列频繁出现在ORDER BY子句中,应考虑在这些列上建立索引。
3.小表不要建立索引。
4.对于含有空值的列,如果经常在查询时查询非空值,建议在该列上建立索引;如果经常在查询时查询空值,建议在该列上建立基于函数的索引。

需求>设计>程序

5.为了提高表连接的性能,应在连接列上建立索引(建立一般普通的索引即可)
6.索引是数据库的一种实体对象,级别类似于表,会占用内存空间,ORACLE会自动进行索引维护,表和索引可以建立在不同的表空间。
7.通过索引可以提升数据的查询速度,但是会相对地降低DML语句的操作速度,尤其是插和改的速度,ORACLE会花费时间在索引维护上,所以说要把握好索引的数量
8.对于列基数比较大的列,适合B-TREE索引,列基数比较小的列,适合位图索引。
9.对于复合索引,至少要引用到索引列中的第一个列才会使用该索引。
10.某列可以出现在多个索引中,但相同的某列或某几列无法多次建立索引。 --就是可以有多个组合,但不能有重复组合,不同顺序的相同几列视为不同组合
11.索引建立后并不一定会被引用,ORACLE会分析整个SQL后做出最优的执行方式。
12.ORACLE会自动在主键约束和唯一约束列上建立唯一索引。
13.对于一般的B-TREE索引,通配符出现在搜索词的首位时不会引用索引
14.在索引列上使用<> !=号时,或对空值进行判断时,索引不会生效
15.通配符出现在搜索词的首位时不会引用索引
16.同一用户下,索引名不能重复。表被删掉时,基于该表建立的索引也会一并删除

禁用索引的语法:
ALTER INDEX IND_NAME UNUSABLE;
重建索引的语法:
ALTER INDEX IND_NAME REBUILD;

alter index 用户名.索引名 coalesce;
注意!
【插入完成后统一维护索引】比【一边插入一边维护】的速度要快!

索引的删除
语法:DROP INDEX IND_NAME;

索引相关的数据字典
所有索引
SELECT INDEX_NAME, --索引名称
INDEX_TYPE, --索引类型
TABLE_NAME, --表名
UNIQUENESS, --是否唯一
STATUS, --索引状态 VALID 可用的 UNUSABLE 不可用的
TABLESPACE_NAME,–表空间
LOGGING --是否记录日志
FROM USER_INDEXES
WHERE 1=1
AND INDEX_NAME = ‘IND_EMP_DEPTNO’
AND TABLE_NAME = ‘EMP’;

索引列
SELECT INDEX_NAME, --索引名称
TABLE_NAME, --表名
COLUMN_NAME, --列名
COLUMN_POSITION, --字段在索引中的位置
DESCEND --排序方式 默认ASC
FROM USER_IND_COLUMNS
WHERE INDEX_NAME =‘IND_EMP_UPENAME’;

索引函数
SELECT INDEX_NAME,
TABLE_NAME,
COLUMN_EXPRESSION
FROM USER_IND_EXPRESSIONS
WHERE INDEX_NAME =‘IND_EMP_UPENAME’;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值