Oracleでのページングについて
ページングについて適当に考えてみた
たとえば
M_USERテーブルがあって列には
ID
,NAME
,REG_DATE
の3カラムあったとして、NAMEで降順、IDで昇順ソートして11〜20件を取得する場合
一般的には
SELECT NUM_USER.ID ,NUM_USER.NAME ,NUM_USER.REG_DATE ,NUM_USER.NUM FROM (SELECT U.ID ,U.NAME ,U.REG_DATE ,ROW_NUMBER() OVER (ORDER BY U.NAME,U.ID) NUM FROM M_USER U) NUM_USER WHERE NUM_USER.NUM BETWEEN 11 AND 20 ORDER BY NUM_USER.NUM
かなと思いますが、
たとえばIDだけ先にソートして範囲取って、それに自己結合する↓とか
SELECT U.ID ,U.NAME ,U.REG_DATE ,PAGE.NUM FROM (SELECT ID_NUM.ID ,ID_NUM.NUM FROM (SELECT ID ,ROW_NUMBER() OVER (ORDER BY NAME,ID) NUM FROM M_USER) ID_NUM WHERE ID_NUM.NUM BETWEEN 11 AND 20) PAGE INNER JOIN M_USER U ON U.ID = PAGE.ID ORDER BY PAGE.NUM
ROWNUMを駆使してROW_NUMBERを使わない↓とか
SELECT D.ID ,D.NAME ,D.REG_DATE ,ROWNUM FROM (SELECT C.ID ,C.NAME ,C.REG_DATE FROM (SELECT B.ID ,B.NAME ,B.REG_DATE ,B.RID FROM (SELECT A.ID ,A.NAME ,A.REG_DATE ,A.RID FROM (SELECT U.ID ,U.NAME ,U.REG_DATE ,U.ROWID RID FROM M_USER U ORDER BY U.NAME ,U.ID) A WHERE ROWNUM <= 20) B ORDER BY B.NAME DESC ,B.ID DESC) C WHERE ROWNUM <= 10 ORDER BY C.NAME ,C.ID) D ORDER BY ROWNUM
多少方法はあると思います。
まぁ100000件のレコードで 上から
COST:7505
COST:8620
COST:3785
でしたので、一番最後のROWNUM方式がCOST的には
パフォーマンスが高くなりました(あくまでCOSTベースですが)
まぁ、ここまでする必要があるのかとも思いますが。。。
汎用性もないし可視性も悪いので実用的ではないですね
と考えるとOracleでは一般的なROW_NUMBERを使用したページングが一番かもしれない
しかしOracleでもさっさとLIMIT作ってほしいなー