Max(rowid)是否走B树索引
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树索引的更多相关文章
- [MySQL] B+树索引
B+树是一种经典的数据结构,由平衡树和二叉查找树结合产生,它是为磁盘或其它直接存取辅助设备而设计的一种平衡查找树,在B+树中,所有的记录节点都是按键值大小顺序存放在同一层的叶节点中,叶节点间用指针相连 ...
- 【转】 数据库系统——B+树索引
原文来自于:http://blog.csdn.net/cjfeii/article/details/10858721 1. B+树索引概述 在上一篇文章中,我们讨论了关于index的几个中重要的课题: ...
- Oracle索引梳理系列(二)- Oracle索引种类及B树索引
版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...
- 数据库系统——B+树索引
原文来自于:http://dblab.cs.toronto.edu/courses/443/2013/05.btree-index.html 1. B+树索引概述 在上一篇文章中,我们讨论了关于ind ...
- 深入研究B树索引(一)
摘要:本文对B树索引的结构.内部管理等方面做了一个全面的介绍.同时深入探讨了一些与B树索引有关的广为流传的说法,比如删除记录对索引的影响,定期重建索引能解决许多性能问题等. 1.B树索引的相关概念 索 ...
- 搞懂MySQL InnoDB B+树索引
一.InnoDB索引 InnoDB支持以下几种索引: B+树索引 全文索引 哈希索引 本文将着重介绍B+树索引.其他两个全文索引和哈希索引只是做简单介绍一笔带过. 哈希索引是自适应的,也就是说这个不能 ...
- InnoDB的B+树索引使用
何时使用索引 并不是在所有的查询条件下出现的列都需要添加索引.对于什么时候添加B+树索引,我的经验是访问表中很少一部分行时,使用B+树索引才有意义.对于性别字段.地区字段.类型字段,它们可取值的范围很 ...
- B+树索引
结构上 B树中关键字集合分布在整棵树中,叶节点中不包含任何关键字信息,而B+树关键字集合分布在叶子结点中,非叶节点只是叶子结点中关键字的索引: B树中任何一个关键字只出现在一个结点中,而B+树中的关键 ...
- [转帖]B树索引、位图索引和散列索引
B树索引.位图索引和散列索引 https://blog.csdn.net/huashanlunjian/article/details/84460436 索引在数据结构上可以分为三种B树索引.位图 ...
随机推荐
- MSSQL数据库后台进程(线程)
与Oracle数据库类似,微软数据库产品MSSQL也有诸多后台进程来保证数据库系统的高效正常运转,由于MSSQL采用的是线程模型,应该叫做后台线程,为了大家易于理解,我们在暂且称之为后台进程,下面我们 ...
- utf8mb4与utf8的区别
今天在测试小程序保存表情时,数据库插入数据时报错ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value: '\xF0\x9F\x98\x8 ...
- 小程序util工具
import wafer from '../lib/wafer2-client-sdk' import tip from './tip' // 时间格式化 const formatTime = tim ...
- Apache升级PHP教程(以5.3.3升级到5.6.30为例)
最简单的LAMP环境搭建当然是通过yum来安装,但由于镜像仓库中的软件版本更新较慢,经常会遇到版本过旧的问题,尤其是安装一些新版本的CMS时的PHP. 这时我们需要手动编译PHP,Linux编译安装经 ...
- cpu占用过高排查
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器 内容解释: PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小 ...
- windows中mysql5.7保存emoji表情
1.找到my.ini文件,修改一下配置: [client] default-character-set=utf8mb4 [mysqld] character-set-client-handshake ...
- python---多线程与多进程
一. 单进程多线程 1. 使用的模块是Threading.使用join()函数进行阻塞. from pdf2txt import pdfTotxt1, pdfTotxt2 import xlrd im ...
- linux网络操作 netstat命令
关闭与启动网卡 ifdown 网卡设备名 #禁用该网卡设备 ifup网卡设备名 #启用该网卡设备 查看网络状态 netstat 命令 -t 列出tcp协议端口 -u 列出udp协议端口 -n 不 ...
- Model1与Model2
Model1与Model2开发模式的介绍及区别 转载 浅析Java开发中的Model1和Model2
- Java代理:静态代理、动态代理
要理解动态代理,需要先理解反射(http://www.cnblogs.com/Donnnnnn/p/7729443.html) 通俗理解: 在很多底层框架中都会用得到,比如struts,Spring等 ...