现有一个系统,数据库从原来的9i升级到了10g,结果出的报表list都乱了。
后来去查了SQL文,发现原来里面有一句最普通的select文(不含group by)没有使用order by,
在9i中是可以按主键自动排序的,到了10g就不按主键排序了。结果我做了以下试验:1。在oracle9i中建了实验的表。
CREATE TABLE GHQ001.TEST
(
    ID                             VARCHAR2(2) NOT NULL,
    PID                            VARCHAR2(2) NOT NULL,
    NAME                           VARCHAR2(10) NOT NULL,
    VALUE                          VARCHAR2(10),
    CONSTRAINT TEST PRIMARY KEY (ID, PID)
)
/2。数据如下:
ID PID NAME VALUE
01 01 aa 1
02 01 bb 1
03 03 cc 1
04 04 dd 1
05 05 ee 1
01 02 aa1 1
02 03 bb2 1
01 04 aa3 1
01 05 aa4 1
01 06 aa5 1
02 02 bb1 1
02 04 bb3 1
02 05 bb4 1
02 06 bb5 1
01 03 aa2 13。用下面3个case的SQL进行检索1)SELECT的字段有且仅有主键,where条件中含且仅含主键(或主键的一部分)select rowid,id,pid from test where id='01'结果如下:(按主键升序)
ROWID  ID PID
AAACZPAADAAAAW1AAA  01 01
AAACZPAADAAAAW1AAF  01 02
AAACZPAADAAAAW1AAO  01 03
AAACZPAADAAAAW1AAH  01 04
AAACZPAADAAAAW1AAI  01 05
AAACZPAADAAAAW1AAJ  01 06
2)2)SELECT的字段有主键以外的字段(name),where条件中含且仅含主键(或主键的一部分)select rowid,id,pid,name from test where id='01'结果如下:(按主键升序)
ROWID           ID PID NAME
AAACZPAADAAAAW1AAA  01 01 aa
AAACZPAADAAAAW1AAF  01 02 aa1
AAACZPAADAAAAW1AAO  01 03 aa2
AAACZPAADAAAAW1AAH  01 04 aa3
AAACZPAADAAAAW1AAI  01 05 aa4
AAACZPAADAAAAW1AAJ  01 06 aa5
3)SELECT的字段有且仅有主键,where条件中含有主键以外的字段(value ='1')select rowid,id,pid from test where id='01' and value ='1'结果如下:(按主键升序)ROWID  ID PID
AAACZPAADAAAAW1AAA  01 01
AAACZPAADAAAAW1AAF  01 02
AAACZPAADAAAAW1AAO  01 03
AAACZPAADAAAAW1AAH  01 04
AAACZPAADAAAAW1AAI  01 05
AAACZPAADAAAAW1AAJ  01 06
以上在9i的试验结果,很好的验证了,为什么在9i的时候不加ORDER BY也可以排序的现象。
接下来,我以DMP的方式把9i中的那张表和数据都做到了Oracle Database 10g Enterprise 
Edition Release 10.2.0.3.0 中。然后用和9i中一样的3个case来做实验。1)SELECT的字段有且仅有主键,where条件中含且仅含主键(或主键的一部分)select rowid,id,pid from test where id='01'结果如下:(按主键升序)
ROWID  ID PID
AAAE4WAAEAABPUYAAA  01 01
AAAE4WAAEAABPUYAAF  01 02
AAAE4WAAEAABPUYAAP  01 03
AAAE4WAAEAABPUYAAH  01 04
AAAE4WAAEAABPUYAAI  01 05
AAAE4WAAEAABPUYAAJ  01 06
2)SELECT的字段有主键以外的字段(name),where条件中含且仅含主键(或主键的一部分)select rowid,id,pid,name from test where id='01'结果如下:(按ROWID来排序)ROWID  ID PID NAME
AAAE4WAAEAABPUYAAA  01 01 aa
AAAE4WAAEAABPUYAAF  01 02 aa1
AAAE4WAAEAABPUYAAH  01 04 aa3
AAAE4WAAEAABPUYAAI  01 05 aa4
AAAE4WAAEAABPUYAAJ  01 06 aa5
AAAE4WAAEAABPUYAAP  01 03 aa23)SELECT的字段有且仅有主键,where条件中含有主键以外的字段(value ='1')select rowid,id,pid from test where id='01' and value ='1'
结果如下:(按ROWID来排序)ROWID  ID PID
AAAE4WAAEAABPUYAAA  01 01
AAAE4WAAEAABPUYAAF  01 02
AAAE4WAAEAABPUYAAH  01 04
AAAE4WAAEAABPUYAAI  01 05
AAAE4WAAEAABPUYAAJ  01 06
AAAE4WAAEAABPUYAAP  01 03
从上可以看出,在第一种case时,10g和9i的表现是一样的。(都是按照主键来排序)
但是,一旦select的字段或者where条件中出现了主键以外的字段时,10g和9i的表现就完全不一样了。
10g:是按照rowid来排序
9i:是按照主键排序这是为什么呢?还请大家帮助解惑啊。此贴送100分(最高只能一百),如果解惑了另外再加。
注意:
调查的初步,发现是按ROWID来排序的,于是就怀疑是不是在9i导入10g时,
数据的ROWID的顺序发生了变化导致,排序也乱了。比如:9i时都是顺序的ROWID,到了10gROWID乱了。所以排序也乱了。
后来发现,9i中的ROWID也不是顺序的,是按主键排序的。
所以,在这次的实验中,不但表和数据一抹一样,我设法把10g和9i的rowid顺序也是一抹一样的。
对策:
现在,系统是正常运行了。因为,加上了order by。
但是这10g和9i的排序问题的根源还是想弄明白。

解决方案 »

  1.   

    应该是你导入的时候物理顺序发生了变化,默认应该是按物理位置排序的。你可以在10G上一条一条的insert来验证一下!
      

  2.   

    TO:kinglht(爱新觉罗至尊宝)谢谢你的回复。
    首先,rowid就是由按物理位置组成的,所以我在注意中写了。
    “我把两张用来试验的表的rowid顺序也弄成一样的了。“目的就是,为了说明10g和9i中的那两张表中的物理位置顺序也是一样的。
      

  3.   

    关系型数据库的数据本身是无序的
    如果你不加order by/distinct/group by之内的导致排序的关键词,
    出来什么样都是有可能的
      

  4.   

    晕倒,不加order by你还想怎么排序?
      

  5.   

    rowid在重新导入表的过程中是会变化的.
      

  6.   

    一定要加order by,这个问题在10g的PPT中有提到,
    9i,group by 默认有排序,10g里算法改了,默认情况下没有排序。
    跟rowid没啥关系,主要是10g的算法改了。
      

  7.   

    嗯.对这点在10G里面是有变化的.你可以通过trace观察出来