转自: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和函数索引的更多相关文章

  1. Oracle索引梳理系列(六)- Oracle索引种类之函数索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  2. Oracle 优化——位图、函数等索引介绍

    一.位图索引 我将使用一个例子,来描述位图索引的存储,并分析它的优点. Table :Loans 放贷信息 ID userId 行业投向 币种 证件类型 还本付息方式 状态 1 1 农业 人民币 身份 ...

  3. 【Oracle 函数索引】一次数据库的优化过程

    [问题]表里数据2万条,查询执行时间 818087.38 ms(12分钟). SQL语句如下:select   F1,F2,F3,F4   from t_sms_g_send t   left joi ...

  4. oracle的位图索引和函数索引

    1.位图索引 位图索引适用于性别.婚姻状态.行政区等只有几列固定值的类型列,身份证号等就不适合位图索引,位图索引适用于静态数据,频繁更新的字段不适用建立位图索引,因为更新会导致索引块区的变更,还会引起 ...

  5. Oracle中的位图索引和函数索引

    位图索引 同样的,先说是什么,再说为什么. 上篇我们说过BTREE索引是将数据表的索引列和行号排序后以树状形式存在磁盘中.那位图索引是什么样的呢? 现有如下日志表,有操作类型字段op_type,该字段 ...

  6. oracle截取字符串,定索引

    转载:https://www.cnblogs.com/qmfsun/p/4493918.html 使用Oracle中Instr()和substr()函数: 1 2 3 4 5 6 7 8 9 10 1 ...

  7. MySQL 5.7新特性之Generated Column(函数索引)

    MySQL 5.7引入了Generated Column,这篇文章简单地介绍了Generated Column的使用方法和注意事项,为读者了解MySQL 5.7提供一个快速的.完整的教程.这篇文章围绕 ...

  8. Oracle中NULL值与索引

    NULL值是关系数据库系统布尔型(true,false,unknown)中比较特殊类型的一种值,通常称为UNKNOWN或空值,即是未知的,不确定的.由于NULL存在着无数的可能,因此NULL值也不等于 ...

  9. Oracle数据库之视图与索引

    Oracle数据库之视图与索引 1. 视图简介 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改. 视图基于的表称为基表,视图是存储在数据字典里的一条SE ...

随机推荐

  1. 安卓qq视频动态名片制作器

    本软件来自互联网,仅供个人参考,严禁商业用途! 非常炫酷的diy动态名片教程,B格绝对高,内含软件教程代码,包会!

  2. 一个最简单的typescript工程

    初级: 1.新建一个文件夹~/a/ 2.cd ~/a/ 3.npm init -y          生成package.json 4.新建index.ts,内容:console.log(" ...

  3. CSS3全览_文本+视觉+盒子+背景颜色

    CSS全览_文本+视觉+盒子+背景颜色 目录 CSS全览_文本+视觉+盒子+背景颜色 1. 文本属性 2. 视觉格式化基础 3. 内边距, 边框, 轮廓和外边距 4. 颜色, 背景和渐变 作者: ht ...

  4. ssl证书---验证等级分类

    DV SSL证书(domain Validation SSL): 指只验证网站域名所有权的简易型SSL证书,此类证书仅能起到网站机密信息加密的作用,无法向用户证明网站的真实身份.所以,不推荐在电子商务 ...

  5. 浅入 AutoMapper

    目录 浅入 AutoMapper AutoMapper 基本使用 映射配置 映射检查 性能 Profile 配置 依赖注入 表达式与 DTO 浅入 AutoMapper 在 Nuget 搜索即可安装, ...

  6. Getting unknown property: common\models\Teacher::auth_Key

    找了一个半小时,不知道为什么会缺少这个属性,数据库里面的字段明明都是有的. 然后随后找到了原因,是因为key中的k大写了,所以无法识别这个属性.把自己坑到了,以此为戒,以后多注意细节问题

  7. ​grafana 的主体架构是如何设计的?

    ​grafana 的主体架构是如何设计的? grafana 是非常强大的可视化项目,它最早从 kibana 生成出来,渐渐也已经形成了自己的生态了.研究完 grafana 生态之后,只有一句话:可视化 ...

  8. rest framework Serializer fields

    串行领域 在表单类中的每个字段不仅负责验证数据,同时也为"清洁" - 它以标准化格式一致. - Django文档 串行字段手柄的原始值和内部数据类型之间的转换.他们还应对验证输入值 ...

  9. GeoServer安装部署流程

    1.双击geoserver-2.13.0.exe进行安装,点击Next进行下一步 2.GeoServer遵循GPL许可,点击I agree继续 3.选择要安装的程序文件目录,点击Next继续 4.点击 ...

  10. Java进阶专题(二十) 消息中间件架构体系(2)-- RabbitMQ研究

    前言 接上文,这个继续介绍RabbitMQ,并理解其底层原理. 介绍 RabbitMQ是由erlang语言开发,基于AMQP(Advanced Message Queue 高级消息队列协议)协议实现的 ...