oracle优化-分页查询新认识
在写这篇文章之前,对分页查询的认识就是经典的三层嵌套:第①层:获得需要的数据,第②层:用rownum限制展示数据的上限,第③层:用rownum的别名rn限制展示数据的下限。
在生产中遇见一个两层嵌套满足分页查询的SQL,兴奋之余拿出来与大家分享。分三步走1:创建测试表;2:经典分页查询展示SQL及执行计划;3:两层嵌套分页查询展示SQL及执行计划
1、创建测试表
SQL>CREATE TABLE TEST_A(ID NUMBER NOT NULL,SYSID NUMBER,STATUS NUMBER,INFO VARCHAR2(2000));
SQL>INSERT INTO TEST_A
SELECT ROWNUM,ROWNUM+1,TRUNC(DBMS_RANDOM.VALUE(1,9)) ,RPAD('*',2000,'*') FROM DUAL CONNECT BY ROWNUM<=100000;
SQL> ALTER table test_a add primary key(id);
SQL>create index ind_status_sysid on test_a(status,sysid);
说明:TEST_A中ID是主键,status字段取值[1,8]且均匀分布。
要求:取TEST_A中status=5的记录,按sysid排序,展示1-1000行。
2、经典分页查询展示SQL及执行计划
SQL> select /*+gather_plan_statistics*/* from
(select rownum rn ,t.* from
(select * from test_a where status=5 order by sysid )t
where rownum<=1000)
where rn >=1;
分析:
第①层获得status=5且按sysid排序的数据
第②层取返回数据的上限:rownum<=1000
第③层取返回数据的下限:rn>=1
查看SQL的执行计划
SQL> select * from table(dbms_xplan.display_cursor('','','allstats last'));
PLAN_TABLE_OUTPUT
SQL_ID 2dtgu07a19fhk, child number 0
-------------------------------------
select /*+gather_plan_statistics*/* from (select rownum rn ,t.* from
(select t.id,t.sysid,t.status from test_a t where status=5 order by
sysid )t where rownum<=1000) where rn >=1
Plan hash value: 503264694
-------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1000 |00:00:00.01 | 957 |
|* 1 | VIEW | | 1 | 1000 | 1000 |00:00:00.01 | 957 |
|* 2 | COUNT STOPKEY | | 1 | | 1000 |00:00:00.01 | 957 |
| 3 | VIEW | | 1 | 11186 | 1000 |00:00:00.01 | 957 |
| 4 | TABLE ACCESS BY INDEX ROWID | TEST_A | 1 | 11186 | 1000 |00:00:00.01 | 957 |
|* 5 | INDEX RANGE SCAN | IND_STATUS_SYSID | 1 | | 1000 |00:00:00.01 | 71 |
-------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN">=1)
2 - filter(ROWNUM<=1000)
5 - access("STATUS"=5)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
30 rows selected.
Elapsed: 00:00:00.04
分析:
Oracle满足条件的数据有1W多条,但是Oracle只取了1000条数据,从A-Rows中可以看出,大大提高了SQL的性能。
因为Oracle在执行SQL的时候会将查询条件推入到内层查询中,查到满足条件的1000条记录,就会返回,在执行计划COUNT STOPKEY上展示出来。
3:两层嵌套分页查询展示SQL及执行计划
SQL> select /*+gather_plan_statistics*/* from (select row_number()over(order by sysid) rn,t.* from test_a t where status=5) where rn between 1 and 1000;
SQL> select * from table(dbms_xplan.display_cursor('','','allstats last'));
PLAN_TABLE_OUTPUT
SQL_ID cj0ds74naryn3, child number 0
-------------------------------------
select /*+gather_plan_statistics*/* from (select row_number()over(order
by sysid) rn,t.* from test_a t where status=5) where rn between 1 and
1000
Plan hash value: 1970407823
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1000 |00:00:00.01 | 957 |
|* 1 | VIEW | | 1 | 1000 | 1000 |00:00:00.01 | 957 |
|* 2 | WINDOW NOSORT STOPKEY | | 1 | 11186 | 1000 |00:00:00.01 | 957 |
| 3 | TABLE ACCESS BY INDEX ROWID | TEST_A | 1 | 11186 | 1000 |00:00:00.01 | 957 |
|* 4 | INDEX RANGE SCAN | IND_STATUS_SYSID | 1 | | 1000 |00:00:00.01 | 71 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(("RN">=1 AND "RN"<=1000))
2 - filter(ROW_NUMBER() OVER ( ORDER BY "SYSID")<=1000)
4 - access("STATUS"=5)
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
29 rows selected.
Elapsed: 00:00:00.03
分析:两层嵌套也达到了,查到满足1000条记录就返回的要求,逻辑读的消耗同样是957。
以上两种分页查询同时满足了取1000条符合条件的流水的目的,且效率高,可直接拿来用在生产中。
oracle优化-分页查询新认识的更多相关文章
- Oracle的分页查询语句优化
Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. (一) 分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT ...
- Oracle中分页查询语句
Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用.O ...
- Oracle 的分页查询 SQL 语句
Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. 分页查询格式: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM T ...
- Oracle 12C -- top-n查询新特性
Oracle 12C -- top-n查询新特性在12C中,增加了一些新的特性.可以指定返回结果集的指定数量的行.或按照百分比返回行. SQL> select count(*) from emp ...
- Oracle 数据库分页查询的三种方法
一.Oracle 数据库分页查询的三种方法 1.简介 不能对 rownum 使用 >(大于或等于 1 的数值).>=(大于 1 的数值).=(不等于 1 的数值),否则无结果.所以直接用 ...
- oracle 的分页查询与mysql 的分页查询
oracle 的分页查询: select * from (select o.*,rownum rn from Persons o) where rn >40 and rn <=60 : ...
- mysql、sql server、oracle数据库分页查询及分析(操作手册)
1.mysql分页查询 方式1: select * from table order by id limit m, n; 该语句的意思为,查询m+n条记录,去掉前m条,返回后n条记录.无疑该查询能够实 ...
- oracle高效分页查询总结
本文参考链接:http://blog.sina.com.cn/s/blog_8604ca230100vro9.html 探索查询语句: --分页参数:size = 20 page = 2 --没有or ...
- Oracle高效分页查询(转)
page --没有order by的查询 -- 嵌套子查询,两次筛选(推荐使用) --SELECT * -- FROM (SELECT ROWNUM AS rowno, t.* -- FROM DON ...
- Oracle中分页查询语句的写法
要动态的变化分页查询的条件,比如pageNow 这个变量表示的是当前是第几页, oracle分页有通用写法,假设一页5行 select * from ( select t.*,rownum rn fr ...
随机推荐
- C++面试八股文:了解sizeof操作符吗?
某日二师兄参加XXX科技公司的C++工程师开发岗位第10面: 面试官:了解sizeof操作符吗? 二师兄:略微了解(不就是求大小的嘛..) 面试官:请讲以下如何使用sizeof? 二师兄:sizeof ...
- 推送服务接入指导(HarmonyOS篇)
消息推送作为App运营日常使用的用户促活和召回手段,是与用户建立持续互动和连接的良好方式.推送服务(Push Kit)是华为提供的消息推送平台,建立了从云端到终端的消息推送通道,本文旨在介绍Harmo ...
- java解析CSV文件(getCsvData 解析CSV文件)
首先需要下载opencsv的jar包 <!-- https://mvnrepository.com/artifact/com.opencsv/opencsv --> <depende ...
- 树莓派使用Golang+MQ135检测室内空气质量
MQ135是一个比较便宜的空气质量传感器,可以用在家庭以及工业场所中.树莓派是一个小巧但很强大的卡片电脑,基于Linux,同时提供了很多硬件接口,方便开发出各种电子产品.Golang是一款简单高效 ...
- 使用JMeter连接达梦数据库的步骤和示例
引言: 本文将介绍如何使用JMeter连接达梦数据库,并提供连接达梦数据库的步骤和示例,帮助您快速开始进行数据库性能测试. 步骤: 1. 下载并安装JMeter:首先,从JMeter官方网站下载并安装 ...
- 2021-3-13 xml的增删改查
public void XmlAdd(string filename, List<People> pList) { try { List<People> peoples = X ...
- 自动刷新服务:nodemon
安装命令: npm install -g nodemon 运行命令: nodemon server.js 运行结果:
- Redis从入门到放弃(6):持久化
1.引言 Redis作为一种高性能的内存数据存储系统,常被用作缓存.会话存储.消息队列等多种应用场景.然而,由于其数据存储在内存中,一旦发生意外或服务器重启,数据就会丢失.为了保障数据的持久性和安全性 ...
- [elasticsearch]部署安装单节点和集群
单点安装 进入安装目录:cd /usr/local 获取安装包: wget http://172.29.50.31/download/ProgramPackage/elasticsearch/elas ...
- 关于Openssh版本升级问题及版本升级到最新版8.7p1流程(CentOS7系统)
前言: 对linux服务器做过漏洞扫描的都知道,常常服务器会被扫出一大堆关于openssh的漏洞,诸如下面这些,而其中的原因就是因为openssh版本比较低.于是就需要升级openssh的版本.下面就 ...