[PHP-users 16693]Re: OCIでのバッチ処理

にゃろめ nyarome @ tenik.co.jp
2003年 7月 15日 (火) 08:06:26 JST


にゃろめです。
自己レスです。

On Tue, 15 Jul 2003 04:28:43 +0900
にゃろめ <nyarome @ tenik.co.jp> wrote:

> 始めまして、にゃろめと申します。
> 
> 環境は Apache1.3.27+oracle8.1.6.0.0+php4.X.X です。
> 現象は4.2.0/4.2.2/4.2.3/4.3.0/4.3.2 でなりました。
> 
> バッチで
> A. OCIParse
> B. OCIBindByName
> C. OCIExecute
> D. OCIFreeStatement
> A〜D を件数分繰り返して以下のような処理時間でした。
> 
> 100 done. 0.494123
> 200 done. 0.479225
> 300 done. 0.511961
> 400 done. 0.500698
> 500 done. 0.558972
> 600 done. 0.601949
> 700 done. 0.506412
> 800 done. 0.480591
> 900 done. 0.488035
> 1000 done. 0.477467
> 
> A,D は一回だけでよいのでB〜C で繰り返すようにしました。
> これで速くなると思ったのですが逆に遅くなりました。
> 
> 100 done. 0.517450
> 200 done. 0.530188
> 300 done. 0.674378
> 400 done. 0.754502
> 500 done. 0.919813
> 600 done. 1.029730
> 700 done. 1.407992
> 800 done. 1.262290
> 900 done. 1.407570
> 1000 done. 1.509448
> 
> top でモニタしているとメモリがどんどん消費されているのが怪しいです。
> php-4.3.2/ext/oci8/oci8.c を見てみるとB でstatement->bindsに詰めています
> がC では開放されないのが原因かと思います。
> 当然D ではzend_list_delete で開放されます。
> 
> 方法としては
> 1. そもそもどこか間違っている。
> 2. D をコピーしメモリだけフリーする関数をソースに追加する。
> 3. 内部的なメモリなのでB を修正しフリーする。
> でしょうか?
> 
> どうすれば、よいのでしょうか~(=^‥^A アセアセ・・・
> 
試しに、方法3をしてみました。
内部変数statement->binds はハッシュですが実際はリスト(しかも追加のみ)として使っ
ているのでD までメモリを食いまくります。
そこで、バインド変数名のハッシュになるようにしてみました。

オリジナル
zend_hash_next_index_insert(statement->binds,&bind,sizeof(oci_bind),(void**)&bindp);
修正
zend_hash_update(statement->binds,Z_STRVAL_PP(name),Z_STRLEN_PP(name),&bind,sizeof(oci_bind),(void**)&bindp);

これにより、2回目以降は上書きされ問題が解消するかと思います。
100 件処理で0.35s になったので30% 高速になりました。
他にも少し処理があるのでOCI 的にはもっとだと思います。

テストはOUT パラメータとかしていないので不十分だと思いますが、ご意見お待ちしてお
ります。




PHP-users メーリングリストの案内