【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,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】B-tree和函数索引相关推荐
- oracle 函数索引
http://bbs.51cto.com/thread-26271-1.html 如何创建oracle函数索引 Oracle8i的很重要的一个新特性就是增加了function-based index这 ...
- oracle索引使用例子,Oracle中利用函数索引处理数据倾斜案例
关于B-Tree.Bitmap.函数索引的相关内容请参考另一篇博文: Oracle中B-Tree.Bitmap和函数索引使用案例总结 通常来说,索引选取的数据列最好为分散度高.选择性好.从索引树结构的 ...
- Oracle函数索引与普通索引
创建一张表,只有很少量的记录状态为'N',而我们只需要查询状态为'N'的记录 SQL> create table test as select 'Y' flag,o.* from dba_obj ...
- oracle中的index函数,Oracle中的索引详解(整理)
一. ROWID的概念 存储了row在数据文件中的具体位置:64位 编码的数据,A-Z, a-z, 0-9, +, 和 /, row在数据块中的存储方式 SELECT ROWID, last_name ...
- Oracle索引梳理系列(六)- Oracle索引种类之函数索引
函数索引 1.1 概述 在实际应用中,当条件列使用函数运算进行数据匹配时,即使该列建立了索引,索引也不会被使用. 如下示例,其中在owner列上建立一个普通b-tree索引,观 察两种查询方式(不使用 ...
- [20180408]那些函数索引适合字段的查询.txt
[20180408]那些函数索引适合字段的查询.txt --//一般不主张建立函数索引,往往是开发的无知,使用trunc等函数,实际上一些函数也可以用于字段的查询. --//以前零碎的写过一些,放假看 ...
- oracle substr(table),oracle中的substr()函数
SUBSTR(cExpression,nStartPosition [,nCharactersReturned]) 其中,cExpression指定要从其中返回字符串的字符表达式或备注字段: nSta ...
- oracle仅部分记录建立索引的方法
今天研究了一下oracle对部分记录建立索引的方法.其实对部分记录建立的索引就是基于 函数的索引.由于部分记录函数化以后,返回了NULL值,而ORACLE索引不索引NULL值, 导致这些记录没有索引条 ...
- mysql计算三角形斜边_MySQL 5.7新特性之Generated Column(函数索引)
MySQL 5.7引入了Generated Column,这篇文章简单地介绍了Generated Column的使用方法和注意事项,为读者了解MySQL 5.7提供一个快速的.完整的教程.这篇文章围绕 ...
最新文章
- CentOS安装中文输入法
- 关于文献检索的一些思考
- 《DBA修炼之道:数据库管理员的第一本书》——1.2节独特的优势
- 商汤首付56亿!上海建成亚洲最大AI“发电厂”,万亿参数大模型训练无压力
- matlab考试资料,MATLAB复习资料
- vector 源码及使用
- 对原生ajax的理解
- 计算机初级考试题库网络管理,计算机基础考试题库(含答案)
- 网页Loading,让页面加载完再显示
- hnu 暑期实训之公交系统
- Asciidoc语法
- 十三、K8s SVC相关操作
- hdu 6205: card card card【输入挂】
- Java-集合第六篇操作集合的工具类Collections
- 创意书签名字_给书签作品起名字-给书签起名字
- 教你轻松又简单的绘制地铁线路图
- 手机ttf楷体文件_楷体繁体ttf 手机楷体字体ttf
- 手写仿淘宝商城页面(html+css+部分js)
- Android知识图谱(持续更新中)
- 操作系统知识点总结(十四)文件保护:文件访问类型和访问控制
热门文章
- 软件测试需要具备的基本职业素养
- Linux 入门教程(摘自www.linuxsir.org)
- 韩剧机器人题材的_穿越、超能力、监狱题材之后,2018年的韩剧盯上了机器人...
- firefox加速技巧
- PowerBI创建基础的日期表
- 个人征信报告解析(机构版)
- C++ STL 之stack
- 若可以通过高速计算机应用牛顿定律,计算机硬件及网络02_牛顿运动三定律ppt课件...
- 哎呦报错啦怎么办?nginx: [emerg] “server“ directive is not allowed here in /usr/local/nginx/conf/nginx.conf53
- 今天真TMD闹心 哎呦我去了!!