やじゅ@アプリケーション・ラボ わんくま支局

目次

Blog 利用状況

ニュース

プロフィール

MSMVP

副問い合わせ(EXISTS)を使った更新(UPDATE)の注意

売上取り消し処理が遅いということで調査していたのですが、構文をみても単純である為、なかなか気がつきませんでした。

結局遅い原因として、副問い合わせ(EXISTS)を使った更新
(UPDATE)において、EXISTSの中に結合条件以外に外側の条件を含めていたため、処理に時間がかかっていたようです。

これにより、別の処理含めても1分→5秒になりました。作成時は件数が少なかったので気が付かなかったのかも知れませんが、反省を含めて掲載しておきます。
ちなみに私が作成したわけではないですが、すぐに気が付かなかったという点では知識不足だったわけです。

UPDATE T_JUCHU_H JH
SET
  KANRYO_KBN = '0'      -- 完了区分 0:未完了 1:完了
WHERE
    EXISTS  (
        SELECT 1
        FROM   T_URIAGE_M UM
  WHERE  UM.JUCHU_NO  = JH.JUCHU_NO
     AND   UM.JOTAI_KBN  = '0'
    --   AND JH.JOTAI_KBN = '0';  ← EXISTS の中にあると遅い
 )
 AND JH.JOTAI_KBN = '0'; ← EXISTS の外にすることで速くなった

一応Oracleですが、他のDBでも同じだと思うので気をつけましょう。


追記: 情報が不足してました。
インデックスは、JH.JUCHU_NOのみ、UM.JUCHU_NO と JOTAI_KBN はありません。

実行計画
consistent gets:SELECT(FOR UPDATE句有り)文 実行時のデータ要求
これ以外の項目はほぼ同じ値

EXISTS内: consistent gets 11657696
EXISTS外: consistent gets 1070

投稿日時 : 2008年4月28日 2:13

コメントを追加

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 9:38 中博俊

それおかしくないですか?
中にも外にもかかなければいけないですよ。

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 10:35 Streetw☆

条件を外に出したときは、
JH.JOTAI_KBNにインデックスがあればそれが使われるようになるので、
それで速くなったんでしょうか?
実行計画を見比べてみたんですが、インデックスがないときは
速度に大きく影響しそうな違いは見られませんでした。

>中にも外にもかかなければいけないですよ。
そもそも内に書くのは変だって思いますけど;、
両方になくても結果は同じじゃないですか?
#どきどきw

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 10:46 片桐

まず、JUCHU_NOってテーブルキー? インデックス?
で、JOTAI_KBNってテーブルキー?インデックス?
で、この2つで、テーブルキー?インデックス?

という情報がないとなんとも判断つかんです。SQL構文で言うなら、どっちでやっても同じだもの。外でやるほうが絞り込み2回に分かれるから、読む側が見落としをやりかねないからEXSITS文使うときには、さくっと1回で絞り込むことが多いんですけどね……

読んでいて思ったのは、早くなった原因が、TableScanからインデックススキャンに処理が変わったためなんだと予測したんで、だとするとキーが絶対に絡むとおもうのでその辺りの情報がほしいなぁ、なんて。

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 11:53 こあら

はじめてコメントさせて頂きます。
ときどき@itに出没しております、こあらと申します。

EXISTS句が実行される回数が違いませんか?

EXISTS内:100%
EXISTS外:JH.JOTAI_KBN = '0'のときだけ

インデックスについては同上。

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 12:58 やじゅ

おお、こんなにコメントが・・・

インデックスは、JH.JUCHU_NOのみ
UM.JUCHU_NO と JOTAI_KBN はありません。

>中にも外にもかかなければいけないですよ。
でも、中に書いたら、あきらかな速度低下があったし

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 13:11 Streetw☆

UM.JUCHU_NOにもインデックスないのですか~
すると、すごく非効率的な処理になってると思います(n×nの走査)。
効率だけで考えると、inner joinしてupdateする方が良さそうです。
というか、インデックス付けたいですw
速くなったのは、こあらさんの理由からですね!

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 13:45 やじゅ

実行計画を見てみました。

consistent gets:SELECT(FOR UPDATE句有り)文 実行時のデータ要求
これ以外の項目はほぼ同じ値

EXISTS内:
consistent gets 11657696
EXISTS外:
consistent gets 1070 

そりゃ遅いわなー

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 13:47 やじゅ

>UM.JUCHU_NOにもインデックスないのですか

インデックスを貼る予定ではいます。

# re: 副問い合わせ(EXISTS)を使った更新(UPDATE)の注意 2008/04/28 15:06 Streetw☆

こういうのって、最適化してくれないんですね。
でも、インデックスなくても速いですね~

作ってるときは気付かずに、使われてるところ見て初めて、
Σこんな遅いので使ってもらってたんですか!
ってときがたまにあります;(ごめんなさい)

# Great beat ! I would like to apprentice even as you amend your web site, how could i subscribe for a weblog website? The account aided me a appropriate deal. I had been a little bit familiar of this your broadcast offered vivid clear idea 2017/12/02 12:51 Great beat ! I would like to apprentice even as yo

Great beat ! I would like to apprentice even as
you amend your web site, how could i subscribe
for a weblog website? The account aided me a appropriate deal.
I had been a little bit familiar of this your broadcast
offered vivid clear idea

タイトル
名前
URL
コメント