[quote="robbin"]
再来看net.sf.hibernate.dialect.Oracle9Dialect:
Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。
[/quote]
Oracle的这种实现如果有order by子句依然有问题。某些时候会导致翻页有记录重复或者遗失,很难找到规律,非常奇怪。
后来去google了一下,有Oracle专家说需要order by的时候必须带上unique的字段,例如主键或者rowid等。
另外,在使用这种采用rownum的查询时,尽管速度相对比较快,但是后台Oracle在内存和CPU的消耗上会增加许多。其实除非结果集非常庞大(几万以上),并且必须翻倒很后面(skip的记录很多),采用ResultSet.absolute方法性能还可以,并没有数量级上的差别。
再来看net.sf.hibernate.dialect.Oracle9Dialect:
public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql) {
StringBuffer pagingSelect = new StringBuffer(100);
pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
pagingSelect.append(sql);
pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
return pagingSelect.toString();
}
Oracle采用嵌套3层的查询语句结合rownum来实现分页,这在Oracle上是最快的方式,如果只是一层或者两层的查询语句的rownum不能支持order by。
[/quote]
Oracle的这种实现如果有order by子句依然有问题。某些时候会导致翻页有记录重复或者遗失,很难找到规律,非常奇怪。
后来去google了一下,有Oracle专家说需要order by的时候必须带上unique的字段,例如主键或者rowid等。
另外,在使用这种采用rownum的查询时,尽管速度相对比较快,但是后台Oracle在内存和CPU的消耗上会增加许多。其实除非结果集非常庞大(几万以上),并且必须翻倒很后面(skip的记录很多),采用ResultSet.absolute方法性能还可以,并没有数量级上的差别。