質問
Ohata Yuji · 2022年9月13日

テーブルアクセス結果の取得APIについて。

こんにちは、皆さま。
業務でIRISを用いて開発を行っている者です。

現在開発している処理の中で、大量データをSELECT & INSERTする処理があり、合計で91分かかっています。
この処理で用いるSQLは実行結果を再利用したい等の意図があったため、ScrollableResultSetを用いていましたが、
このAPI自体がSQL実行時に全件ループを回したり、そもそも古いAPIとの事であったため、
%SQL.Statementに書き換えたところ、62分まで短縮することが出来ました。

ここからが問題なのですが、更なる処理時間の軽減のために時間がかかる処理を調査していたところ、
カラム情報を取得する%Get()メソッドにコストがかかっていることがわかりました。
なので現在はこれを改善したいと思っております。

こちらで動作を見たところ、最速は下記でいう所の「rset.name」でこちらを利用すると、41分まで削減されます。

https://docs.intersystems.com/iris20211/csp/docbookj/DocBook.UI.Page.cls...

しかし、我々としましてはAPIを汎用的に用いたいため、nameの部分を動的に扱えるような%Get()の様な仕組みが欲しいです。

どなたか、「rset.name」相当に高速でアクセス可能な動的なプロパティへのアクセス手段はご存知ではないでしょうか?

 

ちなみに、Xecuteを使って強引に動的にプロパティを取りに行く処理は大変遅く、
$PROPERTY()を用いた方法だと、57分と微妙なところでした。
 

================
現状 91m
①Scrollable廃止 62m
②①+$Property() 57m
③①+プロパティ直読み 41m
================

Product version: IRIS 2022.1
0
0 62
ディスカッション (4)1
続けるにはログインするか新規登録を行ってください

Ohataさん
こんばんは。

カラムデータを取得する際にカラム名ではなく、カラム番号で取得するのは難しいでしょうか?
例えば
    select A,B,C FROM Table
としたときに、Cの値を取りたければ
   set var = rset.%Get("C")
の代わりに
   set var = rset.%GetData(3)
といった感じです。

もし可能でしたら、カラム名からカラム番号に変換するという余分な処理をしなくても済むので
早くなるのではないかと思います。
 

Minamotoさん

ご回答いただきありがとうございます。
そちらの方法も検討したのですが、SELECTで*を使って取得した場合や、
複数のテーブルを結合してアクセスした際に、番号を把握しにくいというのと、
SQLのメンテナンスによって列番号が変わった際の保守性が低いという所より、見送りました。

やはりパフォーマンス劣化は避けられなさそうでしょうか…。

DynamicObjectに対して、「.name」でアクセスするのと、「%Get()」で動的にアクセスするのでは、
実質動作に差異がないと思っていたのですが、SQLからの取得結果へのアクセスとなると、
内部でカラム番号の変換処理が必要になってる、という事なんですね。。。
(であれば、何故直接「.name」でアクセスするのが早いのかは気になりますが…。)

Ohataさん

%Prepare後の%SQL.Statementオブジェクトから%Metadata.columnsを使う等すると、カラム名と番号の紐付けが作れるので、%GetDataも使えると思います。
ただ、%GetDataは私が試したところ、$PROPERTYとほぼ互角でした。
カラム番号が使えるのであれば、%GetRowを使えば 「.name」よりも爆速だと思います(但しIRIS2021以上ですが)

ちなみに、INSERTの方もご検討されると良いかもしれません。

Hashimotoさん

ありがとうございます!
カラム名を渡されたらそちらの%Metadata.columnsから番号を取得して、
%GetRow()で引っ掛けてみる、という事ですね。

一度試してみようと思います。