Max(rowid)是否走B树索引

测试:SQL文本Max(rowid)执行计划是否走B树索引测试

一、猜测执行计划

当SQL语句中,执行max(rowid)时,执行计划猜测:

A走B树索引全索引范围扫描

B走B树索引根-茎-叶块扫描

C不走索引,全表扫描

二、测试

1#测试用户scott,查询索引信息:

SQL>select INDEX_NAME,INDEX_TYPE,UNIQUENESS,TABLE_OWNER,TABLE_NAME from user_indexes where table_owner='SCOTT' and table_name='EMP'

INDEX_NAME INDEX_TYPE UNIQUENES TABLE_OWNE TABLE_NAME

---------- ---------- --------- ---------- ----------

PK_EMP     NORMAL     UNIQUE    SCOTT      EMP

2#SQL文本

SQL> select * from emp where rowid=(select max(rowid) from emp);

SQL> select max(rowid) from emp;

MAX(ROWID)

------------------

AAAVREAAEAAAACXAAN

3#执行计划工具autotrace

SQL> set autotrace traceonly

SQL> select max(rowid) from emp;

| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time

|   0 | SELECT STATEMENT  |        |     1 |    12 |     1   (0)| 00:00:01

|*  1 |  FILTER

|   2 |   SORT AGGREGATE  |        |     1 |    12

|   3 |    INDEX FULL SCAN| PK_EMP |    14 |   168 |     1   (0)| 00:00:01

#走的是索引范围全扫描 猜想中执行计划的A

SQL> select count(*) from scott.emp;  --索引范围全扫描!

COUNT(*)

----------

14

4#小结

max(rowid)走的是索引范围扫描

三、需求改写

#如下:本次有一个SQL语句,查询max(rowid)寻找一行数据,查询这行数据的所有记录

1#SQL文本

SQL> select * from emp where rowid=(select max(rowid) from emp)

2#执行计划:

SQL> select * from emp where rowid=(select max(rowid) from emp)

| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time

--------------------------------------------------------------------------------

|   0 | SELECT STATEMENT        |        |     1 |    38 |     2   (0)| 00:00:01

|*  1 |  FILTER

|   2 |   TABLE ACCESS BY USER ROWID| EMP    |     1 |    38 |     1   (0)| 00:00:01

|*  3 |    FILTER

|   4 |     SORT AGGREGATE          |        |     1 |    12

|   5 |      INDEX FULL SCAN        | PK_EMP |    14 |   168 |     1  (0)| 00:00:01

Statistics

----------------------------------------------------------

4  recursive calls

30  db block gets

6  consistent gets

3#改写SQL

#改写SQL文本:

#需求SQL改写:使用主键empno

#改写SQL最重要的是等价,查询过滤的数据是相同的,这样改写SQL才算优化,否则等同重新定义SQL,不能叫优化SQL,而是重写SQL

#改写前 : 使用max(rowid)提取行记录

SQL> select empno from scott.emp where rowid=(select max(rowid) from scott.emp);

EMPNO

----------

7934

#改写后:使用max(empno)提取行记录:

SQL> select max(empno) from scott.emp;

MAX(EMPNO)

----------

7934

#查询的数据等价:SQL文本如下

SQL> select * from emp where empno=(select max(empno) from emp)

#改写SQL,查看执行计划:

SQL> select * from emp where empno=(select max(empno) from emp)

| Id  | Operation            | Name   | Rows  | Bytes | Cost (%CPU)| Time

--------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                1 |    38 |     1   (0)| 00:00:01

|*  1 |  FILTER

|   2 |   TABLE ACCESS BY INDEX ROWID | EMP   1  |  38 |     1   (0)| 00:00:01 |

|*  3 |    INDEX UNIQUE SCAN      PK_EMP |    1 |   |     0   (0)| 00:00:01 |

|   4 |     SORT AGGREGATE            |        |     1 |     4 |

|   5 |      INDEX FULL SCAN (MIN/MAX)| PK_EMP |     1  |    4 |  1   (0)| 00:00:01

--------------------------------------------------------------------------------

Statistics

----------------------------------------------------------

2  recursive calls

15  db block gets

5  consistent gets

#对比:

1.执行计划方式对比:

虽然从结果对比数据没有明显差异,但是从细节看,其实SQL已经优化了:

从执行计划序列号5看:

改写后是 INDEX FULL SCAN (MIN/MAX)| PK_EMP |     1  查询一行数据、

改写前是 INDEX FULL SCAN        | PK_EMP |    14

#从索引扫描方式改变了:一个是索引唯一值查询,一个是索引全扫描,带来的就是数据量变小

2.查询数据量对比:

但是最终为何没有看到明显的差异,是由于测试的表数据量过小,导致成本优化后差异量少

#本次为啥没有看到直观差异,改写后

请看执行计划序列号二步TABLE ACCESS BY INDEX ROWID | EMP   1 row  |  38 bytes

改写前: TABLE ACCESS BY USER ROWID| EMP    |     1 bytes|    38   bytes

#不管是优化前SQL索引全扫描,还是优化后索引唯一扫描,暂且放下,因为最终从索引找到了唯一的一行数据,ROWID,可以直接从存储对象中,找到数据块。

Oracle读取数据,最小单元以块为单位,因此,实质上,本次优化SQL,修改的是索引范围全扫描,修改为索引唯一扫描,节省的是索引查询的时间

Max(rowid)是否走B树索引的更多相关文章

  1. [MySQL] B+树索引

    B+树是一种经典的数据结构,由平衡树和二叉查找树结合产生,它是为磁盘或其它直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有的记录节点都是按键值大小顺序存放在同一层的叶节点中,叶节点间用指针相连 ...

  2. 【转】 数据库系统——B+树索引

    原文来自于:http://blog.csdn.net/cjfeii/article/details/10858721 1. B+树索引概述 在上一篇文章中,我们讨论了关于index的几个中重要的课题: ...

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

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  4. 数据库系统——B+树索引

    原文来自于:http://dblab.cs.toronto.edu/courses/443/2013/05.btree-index.html 1. B+树索引概述 在上一篇文章中,我们讨论了关于ind ...

  5. 深入研究B树索引(一)

    摘要:本文对B树索引的结构.内部管理等方面做了一个全面的介绍.同时深入探讨了一些与B树索引有关的广为流传的说法,比如删除记录对索引的影响,定期重建索引能解决许多性能问题等. 1.B树索引的相关概念 索 ...

  6. 搞懂MySQL InnoDB B+树索引

    一.InnoDB索引 InnoDB支持以下几种索引: B+树索引 全文索引 哈希索引 本文将着重介绍B+树索引.其他两个全文索引和哈希索引只是做简单介绍一笔带过. 哈希索引是自适应的,也就是说这个不能 ...

  7. InnoDB的B+树索引使用

    何时使用索引 并不是在所有的查询条件下出现的列都需要添加索引.对于什么时候添加B+树索引,我的经验是访问表中很少一部分行时,使用B+树索引才有意义.对于性别字段.地区字段.类型字段,它们可取值的范围很 ...

  8. B+树索引

    结构上 B树中关键字集合分布在整棵树中,叶节点中不包含任何关键字信息,而B+树关键字集合分布在叶子结点中,非叶节点只是叶子结点中关键字的索引: B树中任何一个关键字只出现在一个结点中,而B+树中的关键 ...

  9. [转帖]B树索引、位图索引和散列索引

    B树索引.位图索引和散列索引   https://blog.csdn.net/huashanlunjian/article/details/84460436 索引在数据结构上可以分为三种B树索引.位图 ...

随机推荐

  1. postman系列之批量执行接口测试用例

    postman如何批量执行接口测试用例~其实很简单,但是会给我们的工作带来很多方便~ 比如我们写了几十个测试用例,请求都是同一个服务器IP,一旦服务器IP地址从测试环境搬到线上环境,需要修改所有的服务 ...

  2. 基于Vue + webpack + Vue-cli 实现分环境打包项目

    需求由来:我公司项目上线发布至服务器分为三个环境分别为测试环境.预发布环境.生产环境:前期做法是项目通过脚步打包时由脚步把域名和后缀名之类的全部替换成要发布的环境所需要的,因为我公司的项目比较大由许许 ...

  3. 创建型模式篇(工厂模式Factory Pattern)

    一.工厂模式(Factory Pattern) 1.定义: 在软件系统,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口.提供一种封 ...

  4. html 中一些不常见的标签

    标签 描述 <b> 定义粗体文本. <big> 定义大号字. <em> 定义着重文字. <i> 定义斜体字. <small> 定义小号字. ...

  5. 【转】js 对象按照键值(不分区大小写)排序,生成签名方法

    客户需求小程序端用js生成签名,我们按照要求一步一步解决,并且将请求方法封装到一个utils.js里: 第一步:对关联数组按照键名做正序排序. 第二步:拼接字符串 第三步:将拼接的字符串加上私钥 第四 ...

  6. selinux介绍/状态查看/开启/关闭

    SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统--百度百科. 基于经验来说SELinux在 ...

  7. [转]一次CMS GC问题排查过程(理解原理+读懂GC日志)

    这个是之前处理过的一个线上问题,处理过程断断续续,经历了两周多的时间,中间各种尝试,总结如下.这篇文章分三部分: 1.问题的场景和处理过程:2.GC的一些理论东西:3.看懂GC的日志 先说一下问题吧 ...

  8. 牛客网 PAT 算法历年真题 1010 : 月饼 (25)

    月饼 (25) 时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 月饼是中国人在中秋佳节时吃的一种传统食品,不同地 ...

  9. js之close()方法

    .close()方法只适用于通过window.open()打开的弹出窗口.对于浏览器的主窗口,如果没有得到用户允许是不能关闭的.不过,弹出窗口可以调用top.close()在不经用户允许的情况下关闭自 ...

  10. matlab server mapreduce

    >> Z = server.rpc('zeros', 2, 3);>> Z = [2x3 double] [2x3 double] >> Z{1}ans = 0 0 ...