Oracle数据分页

在制作报表的是时候,我们往往需要将数据库中取得的数据分页显示。但是Oracle本身似乎没有提供一个很方便高效的方法给我们完成这个日常应用。所以只有靠自己了。
在Oracle中分页可以用到的一般有两个,row_number()函数和rownum伪列。
先看看row_number()函数,我们可以这样实现分页:
SELECT * FROM (SELECT t.*,row_number() OVER(ORDER BY t.order_col) AS rn FROM t_table t) WHERE rn BETWEEN start_row AND end_row

这个分页简单明了,但是效率比较低,因为row_number()函数似乎效率不高。
        又:在大数据量的时候,这种方法似乎效率又很高,因为外面用到了rn进行分页,oracle似乎对row_number()进行过优化,会仅仅对需要的那部分数据排序,而不用完成整个排序过程,使用这个方法得到了rownum第二种方法一样的效果。
再看看用rownum伪列进行分页:
SELECT * FROM (SELECT t.*,rownum AS rn FROM (SELECT * FROM t_table ORDER BY order_col) t) WHERE rn BETWEEN start_row AND end_row

这样做效率略高。需要注意的是rownum伪列实在先跟一行数据产生,然后再执行排序的,也就是说如果仅仅
SELECT t.*,rownum FROM t_table t ORDER BY t.order_col
这样获取rownum,得到的rownum是乱序的,所以必须在ORDER BY语句外面再套上一层再获取rownum。当然,如果结果不需要ORDER BY或者ORDER BY的那一列是INDEX,则rownum是顺序的。

因为分页的时候往往先显示第一页,所以我们还可以在提高一点效率:
SELECT * FROM (SELECT t.*,rownum AS rn FROM (SELECT * FROM t_table ORDER BY order_col) t WHERE rownum<end_row) WHERE rn>=start_row

这样因为在现实前面的数据时,可以少加载数据,所以可以提高前面的数据显示效率,让查询页面尽快显示。但是如果翻页到最后一页,则效率会变成和上面一种方法完全一样。
在分页的时候,记录的总数是必须获取的一个数据,在获取记录数的时候切记不要对记录进行排序,因为在这个时候排序是完全没有必要但是却会严重影响性能的一个操作。

不知道还有什么其他更好、更有效率的数据分页方法没有,希望知道的可以指点一下!

猜你喜欢

转载自naso.iteye.com/blog/1539789