fc2ブログ
 

Technology へようこそ
ここは技術者の「経験」と「ノウハウ」のブログです


2010年06月28日

カーソルループの高速化(2)

前回、current of を使用して高速化を図る方法について書いたのですが、
ここにヒントがあります。
前回のサンプルを見ていただくとわかるのですが、
update文が非常にシンプルな形になっていると思います。

カーソルループ中で実行されるSQL文をいかに簡単な形にするか、
という観点が比較的有効です。
つまり、join を最小限にし、キー項目をwhere節で指定して
やることなんですね。つまり、

insert文は、select句を使わずvalue句を使う。
update、delete文は、current ofを使う。

ということです。
具体的には、

カーソル宣言で、ループ内実行SQL文で使用する項目を定義し、フェッチする。
フェッチした変数を使用してSQL文を実行する。

ということです。

declare cursor curTest
select
a,b,c
from
tableB
join
tableC
on
   ・・・・・・      

open curTest

fetch next from curTest into @a,@b,@c

while (@@fetch_status = 0)
begin

update
tableA
set
c = c * 1
where
a = @a

if @@ROWCOUNT = 0 -- 更新対象が無ければInsert
begin
insert
tableA
values
(@a,@b,@c)
end

fetch next from curTest into @a,@b,@c

end

close curTest
deallocate curTest

これにより、カーソルオープン時のコストは多少かかりますが、
join時のコストが削減されます。
カーソルオープンは初回1回のみですが、joinは処理件数分行われますので、
高速化が可能になるというわけです。
しかし、これでカーソルループを使用しない処理よりも高速化が可能か、というと、
残念ながらそうではありません。

例えば、1万件を処理する場合、処理の内容にもよりますので、一概には言えないのですが、

カーソルループ使用:約160秒
カーソルループ未使用:約10秒

くらいの差がでてしまいます。
結局、繰り返しの処理は単純に1回の処理時間×処理件数になってしまいますので、
1回の処理時間をいかにはやくするか?という視点で高速化を行うわけですが、
やはり限界があるわけで・・・。

できるだけ繰り返しを使用せずに処理を記述することが、性能問題には有効です。

[ posted by H.K ]

この記事に対するコメント


この記事に対するコメントの投稿














管理者にだけ表示を許可する



この記事に対するトラックバック
トラックバックURL
http://comfair2.blog24.fc2.com/tb.php/479-ee7d1129
この記事にトラックバックする(FC2ブログユーザー)