【Oracle】B-tree和函数索引
转自:https://www.cnblogs.com/yumiko/p/5957613.html
函数索引
1.1 概述
在实际应用中,当条件列使用函数运算进行数据匹配时,即使该列建立了索引,索引也不会被使用。
如下示例,其中在owner列上建立一个普通b-tree索引,观察两种查询方式(不使用UPPER函数及使用UPPER函数)的执行计划的区别。
--查看表上的数据分布情况,可以确定,对于索引列owner,针对scott以及bi的普通查询,一定会使用索引。
Yumiko@Sunny >select owner,count(*) from test01 group by owner; OWNER COUNT(*)
------------------------------ ----------
SCOTT 11
BI 8
SYS 22909
--为owner列创建普通b-tree索引
Yumiko@Sunny >create index btree_owner on test01(owner);
Index created.
--验证创建的索引
Yumiko@Sunny >select a.INDEX_NAME INDEX_NAME,b.INDEX_TYPE INDEX_TYPE,a.TABLE_NAME TABLE_NAME,COLUMN_NAME,STATUS
2 from user_ind_columns a,user_indexes b
3 where a.INDEX_NAME=b.INDEX_NAME and a.table_name='TEST01'; INDEX_NAME INDEX_TYPE TABLE_NAME COLUMN_NAME STATUS
--------------- --------------- --------------- -------------------- --------
BTREE_OWNER NORMAL TEST01 OWNER VALID --利用索引列,针对列值为BI,进行普通查询
--与预想一样,这里用到了索引扫描
Yumiko@Sunny >select * from test01 where owner='BI';
8 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 725909888
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 92 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST01 | 1 | 92 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | BTREE_OWNER | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OWNER"='BI') Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
16 physical reads
0 redo size
2010 bytes sent via SQL*Net to client
469 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
--清空buffer_cache缓冲区,避免影响后续操作对于物理读的观察。
Yumiko@Sunny >alter system flush buffer_cache;
System altered.
--使用UPPER函数进行条件过滤,并观察执行计划
--通过执行计划,可以明显看出,未使用索引扫描,进而导致大量的物理读操作。
Yumiko@Sunny >select * from test01 where UPPER(owner)='BI';
8 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 262542483
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 229 | 21068 | 158 (1)| 00:00:02 |
|* 1 | TABLE ACCESS FULL| TEST01 | 229 | 21068 | 158 (1)| 00:00:02 |
---------------------------------------------------------------------------- Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(UPPER("OWNER")='BI') Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
697 consistent gets
692 physical reads
0 redo size
1583 bytes sent via SQL*Net to client
469 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
通过上面的示例可以看到,即使条件列建立了索引,当索引列上使用函数进行条件匹配,执行计划将不会选择索引扫描。
1.2 函数索引介绍
为了避免由于在条件匹配时引入函数,导致执行计划不再使用索引,oracle提供了基于函数的索引,进而解决上述问题,提高访问效率。
需要注意的是:
在使用函数索引时,SQL语句中的条件表达式必须与函数索引的表达式完全一致,空格、关键字大小写的可以忽略。如果不完全一致,则无法利用函数索引。
1.3 函数索引示例
紧接上面的例子,这里针对上面示例中,条件出现的函数运算UPPER(owner)建立函数索引。
--在索引列上建立函数索引
Yumiko@Sunny >create index func_owner on test01(UPPER(owner));
Index created.
--查看并验证建立的函数索引
--需要注意的,由于此索引是基于函数建立的,因此columns一列无法显示真正的列名,可以通过user_ind_expressions视图查看
Yumiko@Sunny >select a.INDEX_NAME INDEX_NAME,b.INDEX_TYPE INDEX_TYPE,a.TABLE_NAME TABLE_NAME,COLUMN_NAME,STATUS
2 from user_ind_columns a,user_indexes b
3 where a.INDEX_NAME=b.INDEX_NAME and a.table_name='TEST01'; INDEX_NAME INDEX_TYPE TABLE_NAME COLUMN_NAME STATUS
--------------- ------------------------- --------------- -------------------- --------
FUNC_OWNER FUNCTION-BASED NORMAL TEST01 SYS_NC00014$ VALID
BTREE_OWNER NORMAL TEST01 OWNER VALID Yumiko@Sunny >select * from user_ind_expressions where INDEX_NAME='FUNC_OWNER'; INDEX_NAME TABLE_NAME COLUMN_EXPRESSION COLUMN_POSITION
--------------- --------------- ------------------------------ ---------------
FUNC_OWNER TEST01 UPPER("OWNER") 1
--打开会话追踪
Yumiko@Sunny >set autotrace trace;
--清空buffer_cache缓冲区
Yumiko@Sunny >alter system flush buffer_cache;
System altered. --再次使用UPPER函数进行条件查询,此时执行计划使用索引扫描,进而物理读明显降低。
Yumiko@Sunny >select * from test01 where upper(owner)='BI';
8 rows selected. Execution Plan
----------------------------------------------------------
Plan hash value: 939299437
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 229 | 21068 | 19 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST01 | 229 | 21068 | 19 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | FUNC_OWNER | 92 | | 16 (0)| 00:00:01 |
------------------------------------------------------------------------------------------ Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(UPPER("OWNER")='BI') Statistics
----------------------------------------------------------
32 recursive calls
0 db block gets
8 consistent gets
19 physical reads
0 redo size
1583 bytes sent via SQL*Net to client
469 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
8 rows processed
通过上面的示例可以看到,由于建立了函数索引,执行计划重新选择了索引扫描,物理读(physical reads)明显降低。
1.4 常用的oracle索引视图
较为重要的oracle索引视图如下:
dba_indexes
user_indexes
dba_ind_columns
user_indexes
dba_expressions
user_expressions
其中:
dba_indexes与user_indexes视图,主要涵盖了索引的参数、状态以及关联的表信息,但不包含具体的列信息。
dba_ind_columns与user_ind_columns视图,主要涉及具体的索引列的信息。
dba_expressions与user_expressions视图,主要针对函数索引,可以查看具体的函数信息。
【Oracle】B-tree和函数索引的更多相关文章
- Oracle索引梳理系列(六)- Oracle索引种类之函数索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle 优化——位图、函数等索引介绍
一.位图索引 我将使用一个例子,来描述位图索引的存储,并分析它的优点. Table :Loans 放贷信息 ID userId 行业投向 币种 证件类型 还本付息方式 状态 1 1 农业 人民币 身份 ...
- 【Oracle 函数索引】一次数据库的优化过程
[问题]表里数据2万条,查询执行时间 818087.38 ms(12分钟). SQL语句如下:select F1,F2,F3,F4 from t_sms_g_send t left joi ...
- oracle的位图索引和函数索引
1.位图索引 位图索引适用于性别.婚姻状态.行政区等只有几列固定值的类型列,身份证号等就不适合位图索引,位图索引适用于静态数据,频繁更新的字段不适用建立位图索引,因为更新会导致索引块区的变更,还会引起 ...
- Oracle中的位图索引和函数索引
位图索引 同样的,先说是什么,再说为什么. 上篇我们说过BTREE索引是将数据表的索引列和行号排序后以树状形式存在磁盘中.那位图索引是什么样的呢? 现有如下日志表,有操作类型字段op_type,该字段 ...
- oracle截取字符串,定索引
转载:https://www.cnblogs.com/qmfsun/p/4493918.html 使用Oracle中Instr()和substr()函数: 1 2 3 4 5 6 7 8 9 10 1 ...
- MySQL 5.7新特性之Generated Column(函数索引)
MySQL 5.7引入了Generated Column,这篇文章简单地介绍了Generated Column的使用方法和注意事项,为读者了解MySQL 5.7提供一个快速的.完整的教程.这篇文章围绕 ...
- Oracle中NULL值与索引
NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于 ...
- Oracle数据库之视图与索引
Oracle数据库之视图与索引 1. 视图简介 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改. 视图基于的表称为基表,视图是存储在数据字典里的一条SE ...
随机推荐
- 记一次HBase的NotServingRegionException问题
1. 问题 在hbase测试集群上,访问一些hbase表,均报类似下面的错误:region不可用 Wed Oct 28 14:00:56 CST 2020, RpcRetryingCaller{glo ...
- 关于新创公司所需的icp,网文,软著和备案的申请
刚从一个集团离职来到了创业团队,前期是什么都没有,甚至是公司名字都不知道,哈哈.所以就有了后面的坑踩了一遍又一遍.刚开始是在霍尔果斯注册,结果办icp费了半年的时间,东找西找还没下证.又碰上新疆严查不 ...
- C# 并发编程 (异步编程与多线程)
并发:同时做多件事情 多线程:并发的一种形式,它采用多个线程来执行程序. 并行处理:把正在执行的大量的任务分割成小块,分配给多个同时运行的线程.并行处理是多线程的一种,而多线程是并发的一种. 异步编程 ...
- .net core 3.1 过滤器(Filter) 与中间件与AOP面向切面 与拦截器及其应用
Filter(过滤器) 总共有五种,Authorization Filter,Resource Filter,Exception Filter,Action Filter,Result Filter ...
- 基于LNMP架构搭建wordpress博客之安装架构说明
架构情况 架构情况:基于LNMP架构搭建wordpress系统 软件包版本说明: 系统要求 : CentOS-6.9-x86_64-bin-DVD1.iso PHP版本 : php-7.2.29 ...
- Backdrop Filter
CSS 滤镜 : backdrop-filter backdrop filter属性允许我们使用css对元素后面的内容应用过滤效果. 滤镜: 名称: 方法案例: 效果: blur() 模糊 filte ...
- 【老孟Flutter】2020年总结
2020年是我经历的最不平凡的一年,这一年有遗憾.有收获,有感概,也有庆幸,庆幸自己还活着. 用一句话总结自己的2020,忙并收获着,累并快乐着. <Flutter 实战入门> <F ...
- Vue2+Koa2+Typescript前后端框架教程--04班级管理示例(路由调用控制器)
上篇文章分享了简单的三层模式和基础文件夹的创建,本篇将以示例的形式详细具体的展示Router.Controller.Service.Model之间业务处理和数据传输. 1. 班级管理数据模型创建.数据 ...
- sql 中 foreach 中传入多个不同的参数问题
<!--查找某用户绑定的药物不良反应报告列表--> <select id="selectSurveyListByUserProId" resultType=&qu ...
- C#自定义TemplateImage使用模板底图,运行时根据用户或产品信息生成海报图(1)
由于经常需要基于固定的一个模板底图,生成微信小程序分享用的海报图,如果每次都调用绘图函数,手动编写每个placeholder的填充,重复而且容易出错,因此,封装一个TemplateImage,用于填充 ...