Oracle索引梳理系列(二)- Oracle索引种类及B树索引

摘要:
Oracle索引种类一Oracle索引类型概述oracle索引的种类主要有以下几种:B树索引:oracle默认的索引类型,内部采用二叉树结构,根据rowid实现访问行的快速定位。需要注意的是,oracle会自动为表的主键列创建索引。需要注意的是,oracle不会对包含NULL值的索引列进行索引;但对于组合索引,其中包含NULL值的,这一行会索引。

版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载。转载时,请在文章明显位置注明原文链接。若在未经作者同意的情况下,将本文内容用于商业用途,将保留追究其法律责任的权利。如果有问题,请以邮箱方式联系作者(793113046@qq.com)。


Oracle索引种类

一 Oracle索引类型概述

oracle索引的种类主要有以下几种:

  1. B树索引:oracle默认的索引类型,内部采用二叉树结构,根据rowid实现访问行的快速定位。
  2. 反向索引:反转B树索引的索引列的键值字节,尤其是索引列值递增且批量插入数据时,使索引分布均匀。
  3. 位图索引:通过使用位图,标识被索引的列值,进而管理与数据行的对应关系。主要用于OLAP的系统。
  4. 表簇索引:使用表簇索引必须要使用表簇(cluster)。
  5. 函数索引:通过函数将数据列计算的返回值作为索引键值建立的索引结构。

二 B树索引

2.1 B树索引结构图说明

Oracle索引梳理系列(二)- Oracle索引种类及B树索引第1张

  • 该结构图源自于网络,从图中不难看出,B树索引结构主要由三部分组成:根节点、分支节点、叶子节点。
  • 对于oracle而言,索引的层级号采用倒序的方式,既对于层级数为N的索引,根节点的层级号为N,其下一层的分支节点为N-1,类推。
  • 需要注意的是,oracle会自动为表的主键列创建索引。
  • 需要注意的是,oracle不会对包含NULL值的索引列进行索引;但对于组合索引,其中包含NULL值的,这一行会索引。
  • 需要注意的是,索引发生的I/O次数与索引树的层数成正比,因此有些情况下,采用“反向索引”(后面介绍),可以有效降低层数,今儿优化索引性能。

2.2 B树索引说明 - 分支节点(包含根节点)

  • 对于分支节点块而言,其内部的索引条目采用顺序排列,默认为升序,创建时也可制定为降序
  • 对于分支节点块的索引条目而言,主要两个字段:
    • 该分支节点块下面索引块的最小键值。
    • 链接的索引块地址,该地址指向下面一个索引块。
  • 对于分支节点块的索引条目数量,其大小由数据块大小以及键值长度决定。

2.3 B树索引说明 - 叶子节点

  • 对于叶子节点块而言,其内部的索引条目同样采用顺序排列,默认为升序,创建时可制定为降序
  • 对于叶子节点块的索引条目而言,同样主要包含两个字段:
    • 索引的键值。对于单一列索引,其键值为一个列值;对于组合列索引,其键值为多个列值的组合。
    • 键值的rowid信息。该rowid信息记录表中的相应数据的物理地址。
  • 对于叶子节点块间的关系,采用双向链表,包含了指向上一个叶子节点以及下一个叶子节点的指针,方便一定范围内索引。

2.4 B树索引的实际运用情况

  • 检索的数据列是索引指定列时,只需访问索引块即可完成数据的访问
  • --查看表中的索引信息
    Yumiko@sunny >select index_name,table_name,column_name from user_ind_columns where table_name = 'EMP'; INDEX_NAME TABLE_NAME COLUMN_NAME -------------------- -------------------- -------------------- PK_EMP EMP EMPNO

    --查看索引的类型,normal说明为正常B树索引

    Yumiko@sunny >select INDEX_NAME,TABLE_NAME,index_TYPE from user_indexes where index_name ='PK_EMP';

    INDEX_NAME TABLE_NAME INDEX_TYPE
    ----------------------------------------------------
    PK_EMP EMP NORMAL


    --打开会话追踪 Yumiko
    @sunny >setautotrace traceonly
    --查看执行结果 Yumiko
    @sunny >select empno from emp where empno=7900; Execution Plan ---------------------------------------------------------- Plan hash value: 56244932 ---------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ---------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 4 | 0 (0)| 00:00:01 | |* 1 | INDEX UNIQUE SCAN| PK_EMP | 1 | 4 | 0 (0)| 00:00:01 | ---------------------------------------------------------------------------- Predicate Information (identified byoperation id): --------------------------------------------------- 1 - access("EMPNO"=7900) Statistics ---------------------------------------------------------- 1recursive calls 0db block gets 1consistent gets 0physical reads 0redo size 523 bytes sent via SQL*Net toclient 523 bytes received via SQL*Net fromclient 2 SQL*Net roundtrips to/fromclient 0sorts (memory) 0 sorts (disk) 1 rows processed

    通过上面的执行计划可以看到,检索数据仅仅扫描索引块便返回数据,并未进一步通过rowid进行表的扫描(TABLEACCESS BYINDEXROWID

  • 检索的数据列中,含有未涵盖的索引指定列的时候,将会访问索引块以及数据块进行数据的检索
  • Yumiko@sunny >select index_name,table_name,column_name from  user_ind_columns where table_name = 'EMP';
    
    INDEX_NAME           TABLE_NAME           COLUMN_NAME
    -------------------- -------------------- --------------------
    PK_EMP               EMP                  EMPNO
    
    

    Yumiko@sunny >select INDEX_NAME,TABLE_NAME,index_TYPE from user_indexes where index_name ='PK_EMP';

    INDEX_NAME TABLE_NAME INDEX_TYPE
    ----------------------------------------------------
    PK_EMP EMP NORMAL


    Yumiko
    @sunny >setautotrace traceonly
    Yumiko
    @sunny >select * from emp where empno=7900; Execution Plan ---------------------------------------------------------- Plan hash value: 2949544139 -------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 38 | 1 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| EMP | 1 | 38 | 1 (0)| 00:00:01 | |* 2 | INDEX UNIQUE SCAN | PK_EMP | 1 | | 0 (0)| 00:00:01 | -------------------------------------------------------------------------------------- Predicate Information (identified byoperation id): --------------------------------------------------- 2 - access("EMPNO"=7900) Statistics ---------------------------------------------------------- 0recursive calls 0db block gets 2consistent gets 0physical reads 0redo size 889 bytes sent via SQL*Net toclient 512 bytes received via SQL*Net fromclient 1 SQL*Net roundtrips to/fromclient 0sorts (memory) 0 sorts (disk) 1 rows processed

    通过上面的执行计划可以看到,检索数据在扫描索引块后,进一步通过rowid进行表数据的扫描(TABLEACCESSBYINDEXROWID

  • 检索数据时,当直接访问表数据的成本(访问数据块)优于使用索引访问表数据的成本(访问索引块+数据块)时,将不使用索引扫描。如全表扫描。
  • Yumiko@sunny >select index_name,table_name,column_name from  user_ind_columns where table_name = 'EMP';
    
    INDEX_NAME           TABLE_NAME           COLUMN_NAME
    -------------------- -------------------- --------------------
    PK_EMP               EMP                  EMPNO

    Yumiko@sunny >select INDEX_NAME,TABLE_NAME,index_TYPE from user_indexes where index_name ='PK_EMP';

    INDEX_NAME TABLE_NAME INDEX_TYPE
    ----------------------------------------------------
    PK_EMP EMP NORMAL


    Yumiko
    @sunny >setautotrace traceonly Yumiko@sunny >select * fromemp; 14rows selected. Execution Plan ---------------------------------------------------------- Plan hash value: 3956160932 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 14 | 532 | 3 (0)| 00:00:01 | | 1 | TABLE ACCESS FULL| EMP | 14 | 532 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------- Statistics ---------------------------------------------------------- 1recursive calls 0db block gets 8consistent gets 0physical reads 0redo size 1630 bytes sent via SQL*Net toclient 523 bytes received via SQL*Net fromclient 2 SQL*Net roundtrips to/fromclient 0sorts (memory) 0 sorts (disk) 14 rows processed

    通过上面的执行计划可以看到,当检索全表时,并未进行索引扫描,而是采用全表扫描的方式(TABLE ACCESS FULL),访问数据块,进而取得结果。

免责声明:文章转载自《Oracle索引梳理系列(二)- Oracle索引种类及B树索引》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用log4j日志-配置载入问题bootstrap-table的一些参数配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

再次解决 尝试加载 Oracle 客户端库时引发 BadImageFormatException

依旧是32位和64位的问题,解决思路其实还是要保证生成程序是32位程序且Oracle客户端访问使用32位的即可。 环境是WIN10+ VS2017+ORACLE 11G 32客户端 +orcle未知版本数据库 主要尝试了几个地方: 1、VS 修改了 Web里面的服务器,将服务器修改成了“本地IIS”,主要是不知道系统自带的IIS Express运行是以什么...

MySql分页查询

⒈使用limit进行分页查询   例如:     1.查询前5条记录 1 select * from city LIMIT 5     2.查询第11条-第25条记录       11-1 = 10  (索引从0开始)       25-11+1 = 15  1 select * from city LIMIT 10,15     3.每页8条记录,我要看...

Oracle-数据泵使用

转至:https://www.cnblogs.com/chinas/p/8300955.html#_label0 阅读目录  一、为何选择数据泵方式 二、准备工作 1、目标新库上的操作 2、创建数据备份目录(源库和目标库) 三、导入导出 1、expdp导出 2、impdp导入 四、参数说明 1、expdb (1)关键字及其说明 (2)命令及...

【ES】Head插件操作ElasticSearch增删改查(转载记录)

ES以RESTFul风格来命名API的, 其API的基本格式如下 http://<ip>:<port>/<索引>/<类型>/<文档id> ES的动作是以http方法来决定的: 常用的http方法: GET/PUT/POST/DELETE 启动ES后,打开 D:ProgramFilesESelast...

oracle数据库连接字符串

访问方式 连接字符串 要求 ODBC Driver={Microsoft ODBC for Oracle};Server=myServerAddress;Uid=myUsername;Pwd=myPassword; Oracle Client 7.3以上版本 OLEDB Provider=msdaora;DataSource=MyOracl...

oracle中Blob和Clob类型的区别

一、oracle中Blob和Clob类型的区别BLOB和CLOB都是大字段类型,BLOB是按二进制来存储的,而CLOB是可以直接存储文字的。其实两个是可以互换的的,或者可以直接用LOB字段代替这两个。但是为了更好的管理ORACLE数据库,通常像图片、文件、音乐等信息就用BLOB字段来存储,先将文件转为二进制再存储进去。而像文章或者是较长的文字,就用CLOB...