[pgsql-jp: 30401] Re: カーソルに対するSELECT
Makoto,Yui
yuin @ bb.din.or.jp
2003年 7月 5日 (土) 19:35:38 JST
油井です.
> PostgreSQLのカーソルでは、たとえば1行フェッチする場合だとクエリから1行が
> 得られた時点で処理を中断して返ってきますので、コスト的に意味のあるパターン
> も考えられます。
PostgresのカーソルもバックエンドはResult set一度作っていると,
僕も理解していたのですが違ったでしょうか.
カーソルって基本的にクライアントに結果を分けておくることで(クライアントの)
メモリの消費を抑えるものですよね.
PL/PGSQLのカーソルに限って言えば, その通りではないようですが.
http://www.postgresql.jp/document/pg732doc/programmer/plpgsql-cursors.html
例えば, FOR myrec IN SELECT * FROM node LOOP
なんかでは, FOR ループは自動的に*カーソル*を内部的に使用してメモリの問題を防ぐ.
とあります.
実際FOR LOOPではselect分が複数回走っていました.
#PLANが再利用されるとは言え, この選択は微妙な気もしますが...
#シーケンシャルスキャンか結果セットのサイズによっては逆効果ですよね.
実際, 以前作ったものでFOR LOOPのSELECTがボトルネックになっていました.
実装がどうなっているか(OFFSET使ってるかとか)は調べてないので的外れだったらすいません.
永安さんの本題の方ですが,
>サブクエリを使って何とかひとつにまとめる形を取ろうと思います。
------------------------------
create or replace view myvw as
select * from xml_node;
create or replace view myvw2 as
select * from myvw where id < 100
select * from myvw2
------------------------------
で代用できるものでしょうか. ネストが深くなる場合など, 一時テーブルの方がよいかもしれません.
#viewの制限によりlimitとか使えませんし.
ちなみに
------------------------------
create or replace view myvw as
select * from xml_node;
◯select * from myvw
-- view名を上書き
◯create or replace view myvw as
select * from myvw where id < 100
×select * from myvw
------------------------------
これってエラーになってしまうのですね. バックエンドごと落ちる^^;
仕様かもしれませんが, エラーreplace時にエラー出してくれてもよいかも.
myvwみたら..
SELECT myvw.id, myvw.kind FROM myvw WHERE (myvw.id < 100);
そりゃー, って再帰..?
PL/PGSQLには複数行の結果を保持してくれるものってないのかな.
recordは任意の一行ですよね.
+-------------------------------------------------------------------+
Makoto Yui <yuin @ bb.din.or.jp>
Key fingerprint = 6462 E285 97D8 1323 40C4 F9E5 EB0F 9DE6 1713 219E
+-------------------------------------------------------------------+
pgsql-jp メーリングリストの案内