oracle 分页 有无order by情况不同吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle 分页 有无order by情况不同吗相关的知识,希望对你有一定的参考价值。

偶然性可能会造成一样。
oracle是依靠rownum来分页的,所以rownum成了分页的依据。
而如果你无法保证rownum每次生成都是唯一的话,当然也就导致了分页结果的不唯一。
注意点:
之所以要用上order by 是为了保证每次查询得到rownum是永远唯一。这个的实现就跟order by后面的字段相关,你必须想办法让order by排序所依据的字段是具有唯一性的。一般用主键,或者多个字段组成类主键一样的唯一性,注意多个空值也当做相同,就不是唯一。
一般我们都会写成:
select * from
(
select a.* ,rownum from aaa a where rownum < 10 order by “唯一性的字段或者多字段组”
)
where rownum >1
参考技术A 没有order by,是不能保证你每次的顺序一样的,这是个概念问题.........也是很多初次弄分页的人忽视的问题,当然,很多老手貌似也不知道order by在顺序上的重要性本回答被提问者采纳 参考技术B 相同的

坑,MySQL中 order by 与 limit 混用,分页会出现问题!

blog.csdn.net/qiubabin/article/details/70135556

在Mysql中我们常常用order by来进行排序,使用limit来进行分页,当需要先排序后分页时我们往往使用类似的写法select * from 表名 order by 排序字段 limt M,N。

但是这种写法却隐藏着较深的使用陷阱。在排序字段有数据重复的情况下,会很容易出现排序结果与预期不一致的问题。

比如现在有一张user表,表结构及数据如下:

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
表结构
坑,MySQL中 order by 与 limit 混用,分页会出现问题!
表数据

现在想根据创建时间升序查询user表,并且分页查询,每页2条,那很容易写出sql为:select * from user order by create_time limit pageNo,2;

在执行查询过程中会发现:

1、查询第一页数据时:

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
第一页查询结果

2、查询第四页数据时:

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
第四页查询结果

user表共有8条数据,有4页数据,但是实际查询过程中第一页与第四页竟然出现了相同的数据。

这是什么情况?难道上面的分页SQL不是先将两个表关联查询出来,然后再排好序,再取对应分页的数据吗???

上面的实际执行结果已经证明现实与想像往往是有差距的,实际SQL执行时并不是按照上述方式执行的。这里其实是Mysql会对Limit做优化,具体优化方式见官方文档:

https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html

这个是5.7版本的说明,提取几个问题直接相关的点做下说明。

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
Paste_Image.png

上面官方文档里面有提到如果你将Limit row_count与order by混用,mysql会找到排序的row_count行后立马返回,而不是排序整个查询结果再返回。如果是通过索引排序,会非常快;

这里我们查看下对应SQL的执行计划:

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
Paste_Image.png

可以确认是用的文件排序,表确实也没有加额外的索引。所以我们可以确定这个SQL执行时是会找到limit要求的行后立马返回查询结果的。

不过就算它立马返回,为什么分页会不准呢?

官方文档里面做了如下说明:

坑,MySQL中 order by 与 limit 混用,分页会出现问题!
Paste_Image.png

基于这个我们就基本知道为什么分页会不准了,因为我们排序的字段是create_time,正好又有几个相同的值的行,在实际执行时返回结果对应的行的顺序是不确定的。对应上面的情况,第一页返回的name为8的数据行,可能正好排在前面,而第四页查询时name为8的数据行正好排在后面,所以第四页又出现了。

那这种情况应该怎么解决呢?

官方给出了解决方案:

Paste_Image.png

如果想在Limit存在或不存在的情况下,都保证排序结果相同,可以额外加一个排序条件。例如id字段是唯一的,可以考虑在排序字段中额外加个id排序去确保顺序稳定。

所以上面的情况下可以在SQL再添加个排序字段,比如fund_flow的id字段,这样分页的问题就解决了。修改后的SQL可以像下面这样:

SELECT * FROM `user` ORDER BY create_time,id LIMIT 6,2;

再次测试问题解决!!

END

推荐好文



以上是关于oracle 分页 有无order by情况不同吗的主要内容,如果未能解决你的问题,请参考以下文章

在数据库查询中order by 后面可以给表达式吗?

php sql语句拼接怎么加最后一个分页条件order by id desc LIMIT $pageNum,$numPerPage

SQL 分页查询存储过程中order by 后面不能传变量的问题怎么解决

使用 JPA 按嵌套属性排序时结合 DISTINCT 和 ORDER BY

避坑,Oracle中rownum与order by的执行顺序

我可以在不使用 ROW_NUM () OVER (ORDER BY xxxxx) 的情况下在 Sql Server 中对查询进行分页吗?