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作ってほしいなー