Oracle中排序列中值相同引发的问题

互联网 | 编辑: 何毅 2014-03-31 05:00:00转载

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

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

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

select * from policy order by c;

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

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

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

当你遇到问题的时候,最好写一个测试的例子,例如下面的例子,运行在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.

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

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

下面的结果集是在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

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

同样的测试运行在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

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

答案

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

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

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

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

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

相关阅读

每日精选

点击查看更多

首页 手机 数码相机 笔记本 游戏 DIY硬件 硬件外设 办公中心 数字家电 平板电脑