Oracle排序陷阱
前几天遇到一个问题,发现Oracle存在一个排序问题,在这记录一下。
场景:
有一个类CMS的应用,数据库是Oracle的,其中有这样的一个功能:需要按照文章发布的日期排序分页显示。
程序是用Hibernate进行的QBC方式查询的(其实和查询方式无关,用HQL也一样。),20条一页,数据大概有130条左右,在应用里点下一页发 现只有前3页数据是变化的,之后4~6页显示的数据是一样的,也就是说4~6页没有做分页(或者分页数据不正确)。
经过一翻辛苦的查找,最后终于找到原因了,是因为后台管理人员执行了批量的文章发布,130多条记录里很多文章发布日期一摸一样。导致排序分页在4~6页 的时候数据老是重复。为什么会是这样?同样的数据我导入到MySQL下没有问题(存储引擎用的是InnoDB)。 问题出在Oracle,根据经验我觉得可能是Oracle的存储机制导致的,后来查找了Oralce相关的资料证实了这点。
一般我们用Oracle的表都是堆表(Oracle存储表的一种方式),对于堆表,必须知道他的机制:
全部扫描时,会按命中的顺序来获取数据,而不是以插入的顺序。这是一个必须了解的重要的数据库表概念:一般来讲,数据库表本质上是无序的数据集合。还应该 注意到,要观察到这种效果,不必在INSERT后接下来再使用DELETE;只需使用INSERT就可以得到同样的结果。如果我插入一个小行,那么观察到 的结果很可能是:取出行时默认的顺序为“小行、小行、大行”。这些行并不按插入的顺序获取。 Oracle会把数据放在能放下的任何地方,而不是按照日期或事务的某种顺序来存放。
如果你的查询需要按插入的顺序来获取数据,就必须向表中增加一列,以便获取数据时使用这个列对数据排序。例如,这可以是一个数字列,有一个递增的序列(使 用Oracle SEQUENCE对象)。只需使用一个SELECT,其ORDER BY子句对这个列完成排序,这样就可以模拟插入顺序。这个顺序可能只是近似的,因为序号为55的行很可能在序号为54的行之前提交,因此,数据库中序号为 55的行可能放在前面。
应该把堆组织表看作一个很大的无序行集合。这些行会以一种看来随机的顺序取出,而且取出的顺序还取决于所用的其他选项(并行查询、不同的优化器模式,等 待),同一个查询可能会以不同的顺序取出数据。不要过分依赖查询得到的顺序,除非查询中有一个ORDER BY语句!除非你的查询中有一个 ORDER BY,否则不要指望返回的数据会按某种顺序排序。 (另外,GROUP BY 也不会执行排序!ORDER BY 是无可替代的) 。
我出问题的应用虽然用了排序,但是由于排序基于的发布日期字段存在大量的重复数据,导致Oracle的排序出现问题,所以一般按照某些字段排序后,我们需 要再加一个order by id。
最后终结以下出现此问题的前提:
1、SQL分页
2、用了Oracle的堆表(如果你建表时候没有指定表类型,默认就是堆表)
3、按照且仅按照一个有大量重复数据的字段排序
满足1U2U3之后就会出现我遇到的问题。
分享到:
相关推荐
- **SQL编写规范**:遵循最佳编码习惯,避免性能陷阱。 通过《Oracle 19C SQL调优指南》,DBA能够深入理解Oracle 19C的新特性,掌握SQL调优的理论和实践,有效提升系统的整体性能,为企业的业务运行提供强有力的...
本文将基于一次从Sql Server到Oracle的数据库移植经历,分享一些重要的区别与注意事项,旨在帮助开发者避免一些常见的陷阱,并提供解决这些问题的方法。 #### 二、表名、字段名、存储过程名及变量名长度限制 - **...
Oracle 索引详解 Oracle 索引是数据库性能优化的重要工具,它可以大大加快数据的检索速度,提高系统的性能。但是,索引也存在一些...在 SQL 中有很多陷阱会使一些索引无法使用。例如,使用不等于操作符(、!=)等。
"经典SQL语句大全.doc"和"ORACLE__SQL语句教学.pdf"这两份文档很可能是详尽的实例教程,包含了SQL的常见用法、最佳实践和可能的陷阱。学习这些内容不仅可以帮助你理解和执行基本的SQL操作,还能让你掌握高级特性和...
索引的使用还需避免一些陷阱,例如,不等于操作符(、!=)可能导致索引无法有效利用。例如,查询`SELECT cust_Id, cust_name FROM customer WHERE cust_rating <> 'A'`即使`cust_rating`有索引,也可能导致全表扫描...
5. **其他方法**:除了ROWNUM,还可以考虑使用Oracle的其他高级查询功能,如`FETCH FIRST N ROWS ONLY`(需要Oracle 12c及以上版本),它可以直接用于实现分页,同时保持排序的正确性。 总之,ROWNUM在Oracle中是一...
上篇 开启惊喜之门——带意识地学Oracle 第1章意识,少做事从学习开始 2 1.1 选择先学什么颇有学问 2 1.1.1 梁老师课堂爆笑开场 2 1.1.2 看似跑题的手机分类 4 1.1.3 学什么先了解做什么 5 1.2 善于规划分类才有...
ROWNUM 是 Oracle 中的一种伪列,它可以根据返回记录生成一个序列化的数字。利用 ROWNUM,我们可以生产一些原先难以实现的结果输出,但是因为它是伪列的特殊性,在使用时需要注意一些事项,以免掉入“陷阱”。 特殊...
- 排序:在`ORDER BY`子句中,如果按包含NULL值的列进行排序,NULL值会被视为最大值,即在升序排序中位于最后,降序排序中位于最前。 3. 空值的运算 - NULL值与其他值的算术、比较和逻辑运算结果通常是NULL,这是...
《Oracle SOA 成功成熟度模型白皮书》为企业提供了一个全面的指南,帮助它们在SOA旅程中找到正确的方向,避免常见的陷阱,加速转型进程。通过理解和应用Oracle SOA成熟度模型,企业不仅能够提高SOA项目的成功率,还...
3. `SOUNDEX`函数用于按发音相似度对员工姓名进行排序,这是基于语音索引的一种排序方式。 #### NULL值处理:NVL函数的重要性 在数据库操作中,NULL值常常引发意外的后果,特别是在算术运算中。当操作数包含NULL时...
绑定变量的使用并不局限于简单的等值比较,它同样适用于范围查询、排序和其他复杂的操作。然而,绑定变量也有其局限性。在某些情况下,如当数据分布极度不均匀,或绑定变量导致索引选择不当时,可能反而会降低性能。...
如果你在`ORDER BY`子句之后使用`WHERE ROWNUM`,Oracle会先选择满足`ROWNUM`条件的行,然后再进行排序,这可能会导致效率低下。正确的做法是先排序再筛选,就像上面的例子所示。 其次,`ROWNUM`不会跳过已经满足...
Java软件工程师面试是一个重要的环节...分析面试中的陷阱,例如,过度强调理论而忽视实践经验,或者对技术问题回答得过于模糊,都可能影响面试结果。因此,充分准备,清晰表达,诚实面对自己的不足,是成功面试的关键。
这个文档可能是对每个题目的详细解答和解析,包括了每个问题背后的理论基础、操作步骤以及可能遇到的陷阱。考生可以通过这份文档深入理解每个问题所涉及的Oracle 12c数据库管理概念和技术,如数据存储、备份恢复、...
它被广泛应用于Oracle、SQL Server、MySQL、DB2和PostgreSQL等多种数据库管理系统中。本教程基于“SLQ法则.docx”,涵盖了SQL的基础知识,包括数据库和SQL的基本概念、查询基础和聚合与排序等核心内容。 首先,我们...