[pgsql-jp: 39284] 非同期コマンドの複数実行

河本陽一 komoto.yoichi @ kcc.co.jp
2008年 3月 13日 (木) 18:50:09 JST


こうもとです。

 非同期コマンド(PQsendQueryParams())を二つ連続して(PQgetResult()を
間に入れずに)実行したいのですが、マニュアルからは処理可能かどうかい
まいちわかりません。

 環境は、PostgreSQL 8.1(Debian etchのパッケージで8.1.11-0etch1)です。
 以前取得した、8.1.3のHTML版のマニュアルを見ています。

 やりたいことは、1.5K程度のbyteaフィールドを含む数フィールドを1万レ
コード程度読み込んで内容を解析することです。
 一度に全部読まず、カーソルを使用して最大128個ずつ読んでいます。

 byteaのフィールドを取得しようとすると時間がかかるようなので、裏で
取得要求を投げつつ、取得済みのデータを処理できないかと考えています。
 フローだと、以下のような感じになります。

    現在の処理               希望する処理

        |                         |
        |<-----+            データ取得要求(a)
   データ取得  |                  |<-----------+
+-------+      |     =>     データ取得要求(b)  |
|  データ処理  |                  |            |
|       +------+             データ取得(*)     |  *)aの結果、または
|                        +--------+            |    前回のbの結果
+-------+                |    データ処理       |
        |                |        +------------+
                         |
                         +--------+

 現在の処理では、データ取得の時はpostgresのプロセスが処理をし(その
間メインプロセスは暇)、データ処理の時はメインプロセスが処理をしてい
て、常に片方が忙しく、片方が暇という状態になっています(と思う)。
 そこで、次の作業はわかっているので、前もって実行することができるの
ではないかと思いました。
 データ取得要求を二つ連続して行い、最初の取得結果を処理し、次の取得
結果を処理する前にその次のデータの取得要求をすれば、相対的にDBの処理
待ちの時間が減るのではないかと考えています。

 データ取得要求には、PQsendQueryParams()が適切だと思うのですが、2回
連続して実行することができるかどうかわかりません。マニュアルには、パ
ラメータの違い以外はPQsendQuery()と同じと書いてあり、PQsendQuery()の
説明にはPQgetResult()がNULLを返すまでは再び呼んではならないと書いて
あります。ということは、PQsendQueryParams()も連続で呼ぶことはできな
いということですか。
 カーソルで複数回に分けて取得しようとしているので、同じセッションを
使う必要があり、プロセスを分けるとかもできないと思っています。
 取得したデータのコピーを別プロセスに渡すことはできそうですが、200K
近いデータをコピーするのは重そうですし、処理が複雑になりそうなので避
けたいです。
 PQgetResult()で結果を取得してもPQclear()で開放するまではデータは残っ
ているので、取得した後開放せずに次の要求を投げて、その後データ処理を
して開放するということも考えたのですが、どうなのでしょうか。

 SELECT命令の取得要求中にそのデータを処理する方法なら上記の方法意外
でもよいので、シンプルな実装方法などありませんか。


======================================================================
河本陽一(こうもとよういち)
mailto:komoto.yoichi @ kcc.co.jp




pgsql-jp メーリングリストの案内