oracle高效分页查询总结
本文参考链接:http://blog.sina.com.cn/s/blog_8604ca230100vro9.html
探索查询语句:
--分页参数:size = 20 page = 2
--没有order by的查询
-- 嵌套子查询,两次筛选(推荐使用)
--SELECT *
-- FROM (SELECT ROWNUM AS rowno, t.*
-- FROM DONORINFO t
-- WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
-- AND TO_DATE ('20060731', 'yyyymmdd')
-- AND ROWNUM <= 20*2) table_alias
-- WHERE table_alias.rowno > 20*(2-1); --耗时0.05s -- 一次筛选(数据量大的时候,第一次查询的数据量过大,明显比上面慢,不推荐)
--select * from(
--SELECT ROWNUM AS rowno, t.*
--FROM DONORINFO t
--WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') AND TO_DATE ('20060731', 'yyyymmdd')
--) r
--where r.rowno BETWEEN 20*(2-1)+1 and 20*2; --耗时0.46s --有order by的查询
--嵌套子查询,两次筛选(推荐使用)
--SELECT *
--FROM (SELECT ROWNUM AS rowno,r.*
-- FROM(
-- SELECT * FROM DONORINFO t
-- WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
-- AND TO_DATE ('20060731', 'yyyymmdd')
-- ORDER BY t.BIRTHDAY desc
-- ) r
-- where ROWNUM <= 20*2
-- ) table_alias
-- WHERE table_alias.rowno > 20*(2-1); --耗时0.744s -- 一次筛选(数据量大的时候,第一次查询的数据量过大,明显比上面慢,不推荐)
--select * from (
--SELECT ROWNUM AS rowno,r.*
--FROM(
--SELECT * FROM DONORINFO t
--WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
--AND TO_DATE ('20060731', 'yyyymmdd')
--ORDER BY t.BIRTHDAY desc
--) r
----where ROWNUM <= 20; --这里用>查不到数据 =也查不到数据 <= 或者 < 可以查到数据
----where ROWNUM BETWEEN 20*(2-1)+1 AND 20*2; --查不到数据
----where ROWNUM <=20*2 and ROWNUM > 20*(2-1); --查不到数据
----这是因为查询时,第一条生成的rownum为1,1>20不成立,1=20也不成立,所以这条数据就作废了,依次类推,这样就查不到任何一条数据
--) t
--where t.rowno <=20*2 and t.rowno > 20*(2-1); --可以查到数据耗时:3.924s
---- where t.rowno BETWEEN 20*(2-1)+1 AND 20*2; --可以查到数据耗时:3.919s --采用row_number() over 分页函数
--select *
--from(select d.*,row_number() over(order by d.BIRTHDAY) as rownumber
-- from DONORINFO d
-- WHERE d.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
-- AND TO_DATE ('20060731', 'yyyymmdd')
-- ) p
--where p.rownumber BETWEEN 20*(2-1)+1 AND 20*2; --耗时0.812s select * from (
select *
from(select d.*,row_number() over(order by d.BIRTHDAY) as rownumber
from DONORINFO d
WHERE d.BIRTHDAY BETWEEN TO_DATE ('', 'yyyymmdd')
AND TO_DATE ('', 'yyyymmdd')
) p
where p.rownumber <20*2
) where rownumber > 20*(2-1); -- 耗时0.813s
从以上探索比较,我们得知:
1、ROWNUM
rownum总是从1开始的,第一条不满足去掉的话,第二条的rownum 又成了1。依此类推,所以永远没有不满足条件的记录。
可以这样理解:rownum是一个序列,是Oracle数据库从数据文件或缓冲区中读取数据的顺序。
它取得第一条记录则rownum值为1,第二条为2。依次类推。
当使用“>、>=、=、between...and”这些条件时,从缓冲区或数据文件中得到的第一条记录的rownum为1,不符合sql语句的条件,会被删除,接着取下条。
下条的rownum还会是1,又被删除,依次类推,便没有了数据。
所以上限条件必须放在子查询,而下限条件必须放在外层查询。
2、between and 和 >= and <=
这两者查询效率上来说没有区别,between and 最终也是转为>= and <=
所以select * from (select * from a where a.time >= to_date('19920324','yyyymmdd')) b where b.time <= to_date('20170324','yyyymmdd')
这样的嵌套是没有必要的,可以直接用between and。
3、Oracle通用分页格式
对于没有order by语句的分页:
SELECT *
FROM (SELECT ROWNUM AS rowno, t.*
FROM DONORINFO t
WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
AND TO_DATE ('20060731', 'yyyymmdd')
AND ROWNUM <= page*size) table_alias
WHERE table_alias.rowno > (page-1)*size;
有order by语句的分页
SELECT *
FROM (SELECT ROWNUM AS rowno,r.*
FROM(SELECT * FROM DONORINFO t
WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
AND TO_DATE ('20060731', 'yyyymmdd')
ORDER BY t.BIRTHDAY desc
) r
where ROWNUM <= page*size
) table_alias
WHERE table_alias.rowno > (page-1)*size;
另外我们也可以使用row_number() over函数:
select *
from(select d.*,row_number() over(order by d.BIRTHDAY) as rownumber
from DONORINFO d
WHERE d.BIRTHDAY BETWEEN TO_DATE ('', 'yyyymmdd')
AND TO_DATE ('', 'yyyymmdd')
) p
where p.rownumber BETWEEN size*(page-1)+1 AND page*size;
但是相比前面的并没有什么优势。
oracle高效分页查询总结的更多相关文章
- Oracle高效分页查询(转)
page --没有order by的查询 -- 嵌套子查询,两次筛选(推荐使用) --SELECT * -- FROM (SELECT ROWNUM AS rowno, t.* -- FROM DON ...
- Oracle中分页查询语句
Oracle分页查询语句使我们最常用的语句之一,下面就为您介绍的Oracle分页查询语句的用法,如果您对此方面感兴趣的话,不妨一看. Oracle分页查询语句基本上可以按照本文给出的格式来进行套用.O ...
- Oracle的分页查询语句优化
Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. (一) 分页查询格式: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT ...
- Oracle 的分页查询 SQL 语句
Oracle的分页查询语句基本上可以按照本文给出的格式来进行套用. 分页查询格式: SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM T ...
- 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中分页查询语句的写法
要动态的变化分页查询的条件,比如pageNow 这个变量表示的是当前是第几页, oracle分页有通用写法,假设一页5行 select * from ( select t.*,rownum rn fr ...
- Oracle的分页查询及内联视图和函数处理
1.Oracle的分页常用方式: select * from(select * ,ROWNUM num from table where ROWNUM<=20 ) where num>0; ...
随机推荐
- SQL Server里书签查找的性能伤害
在我的博客上,以前我经常谈到SQL Serverl里的书签查找,还有它们带来的很多问题.在今天的文章里,我想从性能角度进一步谈下书签查找,还有它们如何拉低你整个SQL Server性能. 书签查找—— ...
- Python中 sys.argv[]的用法
Python中 sys.argv[]的用法 因为是看书自学的python,开始后不久就遇到了这个引入的模块函数,且一直在IDLE上编辑了后运行,试图从结果发现它的用途,然而结果一直都是没结果,也在网上 ...
- asp.net core mvc剖析:动作执行
紧跟上一篇文章.通过路由和动作匹配后,最终会得到跟当前请求最匹配的一个ActionDescriptor,然后通过IActionInvoker执行动作. 我们先来看一下IActionInvoker如何得 ...
- iOS开发之Run Loop
1.概述 (1) Run Loop提供了一种异步执行代码的机制,不能并行执行任务. (2) 在主队列中,Main Run Loop直接配合任务的执行,负责处理UI事件.计时器,以及其它内核相关事件. ...
- 豆瓣电影Top250基本信息抓取
豆瓣电影Top250基本信息抓取 最近想看电影,但是想看一些有营养的,所以就去豆瓣上看电影评分,但是豆瓣上的评分没有排序,所以就用python把网站内容爬下来了,然后按评分做了排序.具体代码参见git ...
- iOS 文本转语音(TTS)详解:Swift
上一篇博客讲解了iOS的speech FrameWork语音识别的功能:http://www.cnblogs.com/qian-gu-ling/p/6599670.html,对应的这篇博客就写一下文本 ...
- 平时自己项目中用到的CSS
outline 当选中input元素的时候会出现状态线, outline设置成none就没了 input{ outline:none; } contentditable 设置元素内的文本是否可编辑 ...
- Zkdash安装
zkdash是一个zookeeper的管理界面,也可以作为任何基于zookeeper的配置管理工具,比如:Qconf 1.拉取代码 #git clone https://github.com/irea ...
- jQuery习题
1.在div元素中,包含了一个<span>元素,通过has选择器获取<div>元素中的<span>元素的语法是? 答:$("div:has(span)&q ...
- Realm数据持久化方案的简单介绍和使用(二)
接上篇... 4. 可空属性&默认值&忽略属性 默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法: 遵循协议方法 + (NSArray *)requiredPr ...