OracleでLIMIT ~データのページャー表示などに
Oracleにはmysqlなどで頻繁に扱うLIMIT 0,100などという便利な構文が有りません。
検索すると散々な言われようで、なぜ無いのか不明というエントリーを見かけますが、本当にそう思います。そもそもOracleのテーブルって、登録した順で並ぶという考え方が無いようで、担保されていないようです。
そもそもオートインクリも無いので、mysqlなどで約束事のように最初にidというカラムをオートインクリで設定する、という考え方自体が無いのかもしれません。
で、どうするかって話しですが、以下のようにするようです。
SELECT ID, DATA ,ROWNUM (SELECT ID, DATA, ROWNUM AS RN FROM ORA_TABLE WHERE DATA = '******' ORDER BY ID DESC ) WHERE 1 <= ROWNUM and ROWNUM <= 100
OracleにはROWNUMという、抽出したデータに対して順番に番号を振るための擬似列というものがあるそうで、上のようにフィールド名として設定してやると、番号が取り出せます。
で、その番号の何番目から何番目を取り出すかというのをWHEREに指定します。
ただ、このWHERE句に条件を書いても効いてくれません。なので、サブクエリに条件を書いておき、抽出されたレコードに対して振られたROWNUMの数値を指定する、という形でページャー表現を行います。
後はまぁ、cakeでやるならquery文を実行するだけです。
$list = $this->ORA_TABLE->query($sql);
しかし、どうもこれは全データを呼び出して抽出するようで、cakeで数十万行のレコードに対してこれを行うと、酷く時間が掛かります。この辺りはインデックスなどチューニングしても遅いようで・・・
sqlplusやOracle SQL Developerでは、それほど感じないので、cakeで実行すると遅いのかなと考えています。
そもそもcakephp+Oracleなんて無理があるんだろうなぁ・・・というかWEBでOracleを扱うって自体がそもそも無謀なんだと思われます。
まぁOracleのエントリーでさんざ書いていますが、指定されちゃ仕方がない、という事で。