Oracle索引梳理系列(六)- Oracle索引种类之函数索引
函数索引
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,STATUS2 from user_ind_columns a,user_indexes b3 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 calls0 db block gets5 consistent gets16 physical reads0 redo size2010 bytes sent via SQL*Net to client469 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 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 calls0 db block gets697 consistent gets692 physical reads0 redo size1583 bytes sent via SQL*Net to client469 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 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,STATUS2 from user_ind_columns a,user_indexes b3 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 VALIDYumiko@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 calls0 db block gets8 consistent gets19 physical reads0 redo size1583 bytes sent via SQL*Net to client469 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 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
函数索引
oracle
中创建函数索引即是 你用到了什么函数就建什么函数索引,比如substr
select * from table where 1=1 and substr(field,0,2) in ('01')
创建索引的语句就是
create index indexname on table(substr(fileld,0,2)) online nologging;
Oracle索引梳理系列(六)- Oracle索引种类之函数索引相关推荐
- Oracle索引梳理系列(二)- Oracle索引种类及B树索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(五)- Oracle索引种类之表簇索引(cluster index)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(四)- Oracle索引种类之位图索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(八)- 索引扫描类型及分析(高效索引必备知识)
理解oracle索引扫描类型的特点以及具体触发的条件,对于通过合理地使用索引,进行sql优化至关重要(例如组合索引的引导列的选择问题). 在总结索引扫描类型前,需要再次强调关于索引特点的几个关键点: ...
- Oracle索引梳理系列(九)- 浅谈聚簇因子对索引使用的影响及优化方法
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(七)- Oracle唯一索引、普通索引及约束的关系
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(一)- Oracle访问数据的方法
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(十)- 直方图使用技巧及analyze table操作对直方图统计的影响(谨慎使用)
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- Oracle索引梳理系列(十)- 直方图使用技巧及analyze table操作对直方图统计的影响(谨慎使用)...
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
最新文章
- 【C#实践】三层:初识
- spring + mybatis
- Python入门100题 | 第041题
- 我的Java设计模式-原型模式
- 数字图像处理 空间域锐化 MATLAB实验
- python高级含金量技巧_2020年最新Python开发的高级技巧,面试必学
- Integration Services 学习(5):容器
- js 操作java对象_[Java教程]js 对象操作 对象原型操作 把一个对象A赋值给另一个对象B 并且对象B 修改 不会影响 A对象...
- 文件上传之IIS—put漏洞
- python开发:开源pytesseract文字识别
- 论语十二章原文及翻译
- 迈开职场充电第一步,让我们在这个冬天邂逅社科院杜兰金融管理硕士项目
- 2021年全国计算机能力挑战赛C++决赛,题目分享
- 机器人控制系统的主要功能和特点
- tick_params()--matplotlib
- esp32 wifi 连接
- 美国第四大医疗系统疑遭勒索软件攻击,2000万人资料或泄露
- 关于mysql的utf8、utf8mb3、utf8mb4
- 为您打造别样的海景婚纱!
- 微软校招2015 Beautiful String