转自: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. Day1 字符编码及编码函数

    ord() 函数 获取字符的整数表示chr() 函数 把整数编码转换为对应字符'\十六进制编码\十六进制编码' 可以将字符的整数编码使用十六进制的方式这样写Python字符串类型为str,在内存中以u ...

  2. Oracle 常用语句1

    -- 我是注释信息 sql语句 -- 创建用户: create user 用户名 identified by 密码; create user jack identified by j123; -- l ...

  3. create-react-app 基于TS的项目

    写在前面 最近在用React,发现百度了很多都没有找到基于TS的React项目搭建,很多是老的方法已经属于不成功的了,今天我把最新的搭建基于ts的React的项目分享出来 create-react-a ...

  4. vue第二单元(webpack的配置-学习webpack的常用配置)

    第二单元(webpack的配置-学习webpack的常用配置) #课程目标 掌握webpack的常用配置 掌握如何根据实际的需求修改webpack的对应配置 了解webpack-dev-server的 ...

  5. Django 3.x 原生支持websocket 配置

    websocket.py 1 # websocket.py 2 async def websocket_application(scope, receive, send): 3 while True: ...

  6. matplotlib的学习12-Subplot 多合一显示

    import matplotlib.pyplot as plt # matplotlib 是可以组合许多的小图, 放在一张大图里面显示的. 使用到的方法叫作 subplot. plt.figure() ...

  7. Azure Service Bus(一)入门简介

    一,引言 今天开始学习新的内容 Azure Service Bus(服务总线),其实也叫 "云消息服务",和 RabbitMQ,KafKa的一样都是作为消息通信服务,但是它们直接还 ...

  8. java.io.IOException: Target host must not be null, or set in parameters. scheme=null, host=null, path=/

    使用的 xutils 出现标题中的错误 原因:没有添加 Cookie 1 params.addHeader("Cookie", CurrentUserSettings.getCoo ...

  9. 解决在Filter中读取Request中的流后, 然后再Control中读取不到的做法

    摘要: 大家知道, StringMVC中@RequestBody是读取的流的方式, 如果在之前有读取过流后, 发现就没有了. 我们来看一下核心代码: filter中主要做的事情, 就是来校验请求是否合 ...

  10. 【Mongodb】后台主键_id自增(Java版本)

    ObjectId的选择 创建MongoDB文档时,如果没有赋值ID,系统会自动帮你创建一个,通常会在客户端由驱动程序完成.得到的ObjectId类似于这种   ObjectId使用12字节的存储空间, ...