前天协助SA排错时,通过tbsql sql发现了使用oreder by rowid做排序的sql,我很好奇这种写法,为什么业务逻辑会通过rowid来排序来实现,常常这种疑惑浪费了我很多时间。
先确认两个问题:
1.为什么会使用rowid来排序
2.一个普通的分页sql,物理读排在第一,为什么每次需要消耗356个的物理读
Physical Reads Executions Reads per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----
5,043,897 14,149 356.5 7.7 744.89 53095.33 2800676544
SQL> select/*+ordered use_nl(t1 t2)*/ *
9 from (select rid, rownum as linenum
10 from (select rowid as rid
11 from auc_table
12 where username = 'abc123456789'
13 and approve_status in (0, 1, -9)
14 and ends > SYSDATE
15 order by starts asc,rowid )
16 where rownum <= 100) t1,
17 auc_table t2
18 where t1.linenum >= 1
19 and t1.rid = t2.rowid;
--------------- ------------ -------------- ------ -------- --------- ----
5,043,897 14,149 356.5 7.7 744.89 53095.33 2800676544
SQL> select/*+ordered use_nl(t1 t2)*/ *
9 from (select rid, rownum as linenum
10 from (select rowid as rid
11 from auc_table
12 where username = 'abc123456789'
13 and approve_status in (0, 1, -9)
14 and ends > SYSDATE
15 order by starts asc,rowid )
16 where rownum <= 100) t1,
17 auc_table t2
18 where t1.linenum >= 1
19 and t1.rid = t2.rowid;
引江枫的论断:
oracle9204版本有这个问题:因为不稳定的排序,同样值的记录的位置在排序后不是固定的。假设两条记录,1,a和 1,b,按1排序,那么在第一页的时候,可能最后一条是 1 ,a,翻到第二页,本来第一条应该是1,b的但是因为排序不稳定,可能第一条还是1,a,这样1,b就没有显示出来了