S_a_k_Uの日記みたいなDB

~サクゥーと呼ばないで~

メカニズムの切り分け

Oracleのrownumは検索時にカラムが作られるようなイメージなのか。
検索時に抽出した集合に付かんと意味ねぇもんな。
rownumする検索ってページ処理を想定するから、集合って本来の抽出条件による検索結果になるんよな。
ということは、副問い合わせで本来の抽出を行い、その抽出結果に対してrownumを付けて、その結果について必要な行を抽出するという流れが通常の利用イメージか。

select
  X2.RNO as RNO
  ,X2.DT as DT
  ,X2.TXT as TXT
from
  (
    select
      rownum as RNO
      , X1.DT as DT
      , X1.TXT as TXT
    from
      (
        select
          X.DT as DT
          , X.TXT as TXT
        from
          TBL_X as X
        where
          X.DT >= [開始日時 and X.DT <= [終了日時]
        order by
          X.DT
      ) as X1
  ) as X2
  where
    X2.RNO >= [開始行番号] and X2.RNO <= [終了行番号]

X1の時点で、日時で抽出&ソートを実行。
X2の時点で、日時で抽出された結果に対してrownumを付ける。
最終的にX2のRNO(rownum)で抽出。


Oracle的にはこうしろとな。
トップN分析、上位 n レコード、 n〜m レコードの取得
http://biz.rivus.jp/technote507129.html

【ROW_NUMBER 関数 の場合】
SELECT NO FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY NO) RNO, NO FROM ROWNUM_TEST
)
WHERE RNO BETWEEN 5 AND 10
ORDER BY NO;
【インラインビューの場合】
SELECT NO  FROM (
  SELECT NO, ROWNUM RNO FROM (
    SELECT NO FROM ROWNUM_TEST
    ORDER BY NO
  )
) WHERE RNO BETWEEN 5 AND 10
ORDER BY NO;

仕組みを素直に解釈したら、インラインビューってパターンってことになるんじゃろうな?


これは、本来の抽出の結果(日時で抽出された結果)がある程度絞られるという前提にねぇとおえんのじゃろうな。
大量のレコードにrownumを付けることになる=レスポンスが低下するという状態なんじゃろうから。


でも、よっぽど関数使って戻り値をカラムとする方がコストが高いような気がする。
rownumだとレコード順に対して、シーケンス番号だけ(配列のインデックスみたいなもん)って気がする訳で。
例えば、timestamp型(日時)から日付が欲しい場合、SQLで日付にするんじゃなくてアプリで日付にする方がええってことじゃわな。
で、rownumについては、アプリではそのレコード単独では求まらない。
最初のレコードから何番目ってことにせんと求まらん所が、アプリでフェッチするかどうかみたいなことになる訳じゃな。



IBATIS - WicketWiki - Paging
http://www.wicket-wiki.org.uk/wiki/index.php/IBATIS#Paging
アプリ側(フレームワーク内)でなんとかするってパターンか。
でもすべてのelementをDBから取得するから気をつけろってw


DBFlute - Tips: Paging
http://dbflute.sandbox.seasar.org/ja/tips-paging.html
S2のDBFluteなんかもアプリ側(フレームワーク内)でなんとかするってパターンか。


フレームワーク内でこういう仕組みで作ってるんなら、ResultSetのインスタンス化についてわしが過剰に考え過ぎとんかな?という気もするな。としたら、あのSelect文でのバイナリのカラムの有無でのレスポンスの差はどう説明するんな?
とは言え、PostgreSQLJDBCドライバ?DBMS?の実装って話にはならんじゃろ???
iBATISのResultMapのインスタン化の問題なんか???iBATISのPagingの注意書きは正にそのことよな。
でも、ResultSetに対してgetByteする時点で、アプリ側にデータがあるんじゃろ???
そこはiBATISの領域じゃねぇじゃろ???


それとは別に、そもそも大量のレコードを抽出する=その要件に対する検索は適切なのか?ってのがあるわな。
100万件の検索結果を見て利用者はどうすんな?みたいな。
仮にそれを実現する場合どうするか…
同時リクエスト数なんかも気になるし、やっぱDBMSとアプリ間は必要なデータだけの受け渡しにしときてぇよなぁ〜
これがシステム全体の中で大きなウェイトを占めるんなら、DBMSサーバ側(PL/SQLRMI?とか)のメカニズムで解決?って感じだけど、なんかもっとシンプルに解決できんもんかな?


なんかみんな決定的な解決策は持ってねぇっぽいなw
http://www.google.co.jp/search?hl=ja&q=sql+paging&lr=