This queston came up on the Oracle newsgroup a few days ago:

这个问题在Oracle的新闻中心被提出了一段时间:

I have a table (call it policy) with three columns a, b and c. The table has two rows, with column c having value zero for both rows. I run the following query

有个表(表名是Policy),有三个字段:a、b、c,这个表有两行,c列中的数据始终为0,我运行一下的sql语句

select * from policy order by c;

As both the rows have a value of zero, the result should be sorted ascending by rowid, but I see the opposite;  viz. the result set is sorted descending by rowid.

照理说,结果应该按照rowid来升序排序,但是相反的是,结果却按照rowid降序排序。

Is that an issue with the version of 10g server, I am using or is it some settings of the Oracle server?

这个是10g的问题,还是我使用的问题,或者还是设置的问题?

Various people replied to say that you should never assume any ordering beyond the order you explicitly state in the order by clause. But the question does raise a couple of interesting points.

其他的人说,最好是显式的声明排序的条件,比如rowid desc。但是这个问题引发了一个有趣的观点。

Let’s start by running the test (it’s not hard to write up a test case, so why not do so when you ask the question). The following is good enough – and I’ve appended the output of the query when running on 10.2.0.1:

当你遇到问题的时候,最好写一个测试的例子,例如下面的例子,运行在10.2.0.1上:

drop table t1;
create table t1 (a number, b number, c number); insert into t1 values(1,1,0);
insert into t1 values(1,1,0); commit; select t1.*, t1.rowid from t1 order by c; A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAATncAAGAAABSKAAB
1 1 0 AAATncAAGAAABSKAAA

2 rows selected. Sure enough, the results are in the “wrong” order.

两行数据被查询出来,果然数据排序错误。

So what do you do next ? The first couple of ideas are: add a third, fourth and fifth row to see if the “descending order” observation is accurate; then try running the test on a different version of Oracle.

接下来你要怎么做?第一个想法是,添加第三行、第四行、第五行数据,查看“descending order”是否准确,然后运行在不同版本的oracle中。

Here’s the output from 10.2.0.1, after adding more and more rows:

下面的结果集是在10.2.0.1中添加第三行、第四行、第五行数据,并查询的结果

         A          B          C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAATncAAGAAABSKAAA
1 1 0 AAATncAAGAAABSKAAC
1 1 0 AAATncAAGAAABSKAAB A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAATncAAGAAABSKAAA
1 1 0 AAATncAAGAAABSKAAD
1 1 0 AAATncAAGAAABSKAAC
1 1 0 AAATncAAGAAABSKAAB A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAATncAAGAAABSKAAA
1 1 0 AAATncAAGAAABSKAAB
1 1 0 AAATncAAGAAABSKAAE
1 1 0 AAATncAAGAAABSKAAD
1 1 0 AAATncAAGAAABSKAAC

The results are NOT in descending order of rowid – it just looks that way in the very first case.

结果是并没有按照rowid进行降序排序,

But here’s the output from the same test running on 9.2.0.8:

同样的测试运行在9.2.0.8:

         A          B          C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAALJkAAJAAABIKAAA
1 1 0 AAALJkAAJAAABIKAAB A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAALJkAAJAAABIKAAA
1 1 0 AAALJkAAJAAABIKAAB
1 1 0 AAALJkAAJAAABIKAAC A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAALJkAAJAAABIKAAA
1 1 0 AAALJkAAJAAABIKAAB
1 1 0 AAALJkAAJAAABIKAAC
1 1 0 AAALJkAAJAAABIKAAD A B C ROWID
---------- ---------- ---------- ------------------
1 1 0 AAALJkAAJAAABIKAAA
1 1 0 AAALJkAAJAAABIKAAB
1 1 0 AAALJkAAJAAABIKAAC
1 1 0 AAALJkAAJAAABIKAAD
1 1 0 AAALJkAAJAAABIKAAE

So is seems more likely that there is a sorting effect (possibly accidental) on rowids in 9.2.0.8.

在9.2.0.8中,是按照rowid进行了升序排序

The Answer

Oracle introduced a new sorting algorithm (sometimes known as the Version 2 sort, which is how it is labelled in the 10032 trace) in 10.2.

答案

Oracle 10.2引入了一个新的排序算法,称为版本2。

The previous algorithm was effectively building an in-memory index on the incoming data using a balanced binary tree and seeking to the righ (i.e. optimised towards data that appeared in the correct order and keeping such data in the order of appearance - hence the apparent sorting of rowids in our example in 9i).

前面的例子有效的构建一个内存中索引输入数据使用平衡二叉树和(即优化对数据出现在正确的顺序和保持这些数据出现的顺序,明显的例子就是9i的查询结果)

The CPU and memory overheads for this algorithm are a bit fierce for large sorts, so the new algorithm does something completely different (possibly based on a variant of the heapsort, though it isn’t actually a heapsort) which is more efficient on memory and CPU. It has the side-effect though, of re-ordering incoming rows even when the data is not arriving out of order.

这个算法的cpu和内存开销有点大,所以新的算法做了一些改变。类似于堆排序的一种变体,但不是堆排序。它也有副作用,就是重新排序行

Someone who knew their sorting algorithms really well might even be able to infer the algorithm Oracle was using by extending the test case and watching the rowids re-ordering themselves as the result set grows. But I’m not going to volunteer for that task.

人们知道他们的排序算法很好,但是我不愿意做小白鼠。

If you want to disable the new sorting mechanism, there is a hidden parameter to affect it. As usual, you shouldn’t use hidden parameters without first receiving confirmation from Oracle support that you need to, but the relevant parameter is: _newsort_enabled, which defaults to true in 10g.

如果你想禁用新的排序机制,有个隐藏的参数“_newsort_enabled”,默认为true。

原文出处:http://jonathanlewis.wordpress.com/2007/06/03/sorting/

参考资料:http://blog.sina.com.cn/s/blog_6ff05a2c0100mlco.html

Oracle中排序列中值相同引发的问题(译)的更多相关文章

  1. opencv-11-中值滤波及自适应中值滤波

    开始之前 在上一篇我们实现了读取噪声图像, 然后 进行三种形式的均值滤波得到结果, 由于我们自己写的均值滤波未作边缘处理, 所以效果有一定的下降, 但是总体来说, 我们得到的结果能够说明我们的算法执行 ...

  2. oracle 序列中cache 有什么用途

    create sequence name increment by x //x为增长间隔 start with x //x为初始值 maxvalue x //x为最大值 minvalue x //x为 ...

  3. Oracle 修改序列的初始值

    Oracle 序列(Sequence)主要用于生成主键.但是,有时需要修改序列初始值(START WITH)时,好多人凭感觉认为:Alter Sequence SequenceName Start W ...

  4. oracle序列中cache和nocache

    首先我这篇博客的内容是我不知道oracle里的 cache 是什么,结果越查越多... "序列的cache通常为 20,但在需要依据序列值判断创建的先后顺序时必须是 NOCACHE" ...

  5. Oracle修改序列(Sequence)起始值问题

    Oracle 序列(Sequence)主要用于生成流水号,在应用中经常会用到,特别是作为ID值,拿来做表主键使用较多. 但是,有时需要修改序列初始值(START WITH)时,有同仁使用这个语句来修改 ...

  6. ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍

    如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...

  7. 快速排序 之添加复合插入排序和原始序列取中值左pivot

    quicksort中,当n小于一定值时,排序效率就比直接插入排序底了,所以,此时就不要再递归下去了,直接插入排序好了:快速的原理就是因为折半递归,所以初始pivot应该有个好一点的选择,这里在原序列左 ...

  8. 通过oracle闪回查看表中值的变更履历信息

    http://www.oracle.com/technetwork/cn/articles/week1-10gdba-093837-zhs.html 得到电影而不是图片:闪回版本查询 不需要设置,立即 ...

  9. HDU 6464.免费送气球-动态开点-权值线段树(序列中第first小至第second小的数值之和)(感觉就是只有一个状态的主席树) (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)

    免费送气球 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

随机推荐

  1. 多线程和并发管理 .NET多线程服务

    线程相关静态变量 默认静态变量应用程序域所有线程可见.如果静态变量需要在线程间共享,同步访问也就必然了. 线程相关静态变量保证线程安全,同一时间只有一个线程可访问,且每个线程都有该静态变量的拷贝. p ...

  2. 10分钟学会AngularJS的数据绑定

     前言:为什么要用AngularJS?  相信用过.NetMVC的人都知道用rezor绑定数据是一件很爽的事情,C#代码直接在前台页面中输出.然后这种比较适用于同步请求.   当我们的项目离不开异步请 ...

  3. 经典的iptables shell脚本

    PS:这个iptables脚本不错,很实用,根据实际应用改一下就可以自己用.分享出来,供大家来参考.原作者佚名.源代码如下: #!/bin/sh modprobe ipt_MASQUERADE mod ...

  4. VirtualBox 导入.vdi文件时报“uuid is exists”错误

    解决办法: 1.要安装的.vdi文件所在目录:D:\developTools\vm\RedHatLinux1.vdi 2.找到VirtualBox的安装目录,这里是D:\Program Files\O ...

  5. iOS中通知中心NSNotificationCenter应用总结

    通知中心(NSNotificationCenter)实际是在程序内部提供了一种广播机制.把接收到的消息,根据内部的消息转发表,将消息转发给需要的对象.这句话其实已经很明显的告诉我们要如何使用通知了.第 ...

  6. python编写telnet登陆出现TypeError:'str' does not support the buffer interface

    python3支持byte类型,python2不支持.在python3中,telnet客户端向远程服务器发送的str要转化成byte,从服务器传过来的byte要转换成str,但是在python2不清楚 ...

  7. VMware系统运维(九)VMware vSphere Client 安装

    1.点击下一步 2.接受协议,下一步 3.选择安装位置,下一步 4.开始安装 5.安装完成,进行登录测试. VMware vsphere 5.1 登录名为administrator    VMware ...

  8. oracle PL/SQL(procedure language/SQL)程序设计之游标cursors

    游标 Cursors--Conception 每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SE ...

  9. uva 12549 最大流

    思路:这题的原型题是比较经典的网络流.原型题模型就是把所有的障碍去掉. 有障碍做法还是一样的,只用将每个列和行重新划分,求最大流就行了. #include <cstring> #inclu ...

  10. sql server 中 syscolumns 各个字段的意义

    列名 数据类型 描述 name sysname 列名或过程参数的名称. id int 该列所属的表对象 ID,或与该参数关联的存储过程 ID. xtype tinyint systypes 中的物理存 ...