【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 ...
随机推荐
- Mybatis学习-日志与分页
日志 为什么需要日志 如果一个数据库操作出现了异常,需要排错,那么日志就是最好的助手 Mybatis通过使用内置的日志工厂提供日志功能,有一下几种实现方式: SLF4J Apache Commons ...
- JavaSE08-ArrayList
1.ArrayList类概述 什么是集合 提供一种存储空间可变的存储模型,存储的数据容量可以发生改变 ArrayList集合的特点 底层是数组实现的,长度可以变化 泛型的使用 用于约束集合中存储元素的 ...
- 除了MD5加密,试一下签名吧
需求 MD5加密,简单密码用彩虹表很容易破解. 密码不能被暴力破解,可以根据定制字符,时间戳等防止破解 解决方案 签名 密码加密 源码 const crypto = require('crypto') ...
- learn Docker from scratch (1)
一.前言 Docker容器一个很有趣的东西,下面链接内容适合docker的入门非常棒! 链接如下: http://www.ruanyifeng.com/blog/2018/02/docker-tuto ...
- 微服务之服务治理_Eureka
首先需要明确,不管是什么事物需要"治理",那一定是该事物存在一定问题.比如环境治理.那么服务,或者说微服务为什么需要治理?对于服务来说,如果它承担的业务职责简单,那其实治理的必要性 ...
- Gopher协议在SSRF漏洞中的深入研究
如果需要大佬写好的脚本,可以直接去github上面搜 参考文章:https://zhuanlan.zhihu.com/p/112055947 https://www.cnblogs.com/Konmu ...
- 精尽Spring MVC源码分析 - HandlerExceptionResolver 组件
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- Thymeleaf是个什么东东?
Thymeleaf是面向Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本. Thymeleaf的主要目标是提供一个优雅和高度可维护的创建 ...
- draggable()拖拽时限制移动区域
jQuery-UI为我们提供了一个非常便捷的拖拽方法:draggable(),在使用此方法时,我们可能会希望控件只在某一区域中移动,不能被拖出边界,这样的话我们可以使用下面的方法: 调用draggab ...
- C语言丨博客作业03
这个作业属于哪个课程 https://edu.cnblogs.com/campus/zswxy/SE2020-3/ 这个作业要求在哪里 https://edu.cnblogs.com/campus/z ...