1
update auditdata set TATCallType='12',TATCallUnit='1' from auditdata auditdata 
        inner join Auditdata_sms_12 a_sns
        on auditdata.ID = a_sns.id

上記のクエリを実行すると、実行に 10 分以上かかります。

これで何が悪い

Auditdata.ID主キーです..

Updateコマンドを実行すると、インデックスも更新されますか??? これが更新の取得が遅い理由ですか

4

4 に答える 4

2

ここでいくつかのことが行われます。

まず、SQL ステートメントが壊れているように見えます。更新の "FROM" 句は、JOIN された更新として使用するように設計されています。ハードコーディングされた値で行を更新しているため、その必要はありません。

第二に、より難解なことに、インデックスがすべてあなたが言うように正しい場合、おそらく最初の書き込みまたはトランザクション ログ領域 (Oracle では元に戻す、SQL Server ではログなど)。

健全性チェックとして、2 つのことを行います。1 つ目は、まだ条件が設定されていない行のみを更新することです。多くの DBMS 製品は、変更されない行に対して物理ディスク I/O を問題なく実行します (ただし、多くの製品は変更しません)。限界でやってみる。

2 つ目は、更新プログラムを小さなバッチで適用することです。これは、ログの競合やディスクの速度が遅い場合に非常に役立ちます。

したがって、次のようなものを最初に試してください。

UPDATE auditdata 
   SET TATCallType = '12' 
     , TATCallUnit = '1' 
  FROM auditdata 
 WHERE TATCallType <> '12' 
   AND TATCallUnit <> '1'
   AND EXISTS( SELECT *
                 FROM Auditdata_sms_12 a_sns 
                WHERE a_sns.id = auditdata.ID )

バッチを実行したい場合、SQL Server では非常に簡単です。

SET ROWCOUNT 2000

UPDATE ...

(run continually in a loop via T-SQL or by hand until @@ROWCOUNT = 0)

SET ROWCOUNT 0
于 2009-07-14T17:19:21.823 に答える
1

コメントを見ると、メイン テーブルには一時テーブルよりも少ない行が含まれています。

EXISTS 句を使用してみてください (または、ある意味で、比較を少ない行数 (つまり 1500000) に減らします)

update auditdata set TATCallType='12',TATCallUnit='1' 
from auditdata auditdata 
WHERE EXISTS 
(SELECT id from Auditdata_sms_12 a_sns WHERE a_sns.id = auditdata.ID)

アイデアは、比較を制限することです。

編集: AuditdataSMS12 には、行をすばやく取得できるように ID にインデックスが必要です。これは、特定の ID を実際に検索しているテーブルです。

于 2009-07-14T16:34:14.770 に答える
0

更新 最初のクエリをもう一度読んだ後、プライマリ ID フィールドではなく、他の 2 つのデータ フィールドを更新していることに気付きました。私の回答の最初のステートメントをもう一度読み、それに応じてコメントしてください。ごめん。

更新しているいずれかのフィールドにクラスター化インデックスが定義されていますか? クラスター化されたインデックスには利点があります。私はそれらを手に負えませんが、更新中にパフォーマンスに大きな影響を与える可能性があります。私の理解では、クラスター化されたインデックスを更新すると、インデックス全体を再コンパイルする必要が生じる可能性があります。テーブルに大量のデータがある場合、これは間違いなく問題を引き起こす可能性があります。

また、テーブルにトリガーがないことを確認してください。正しく動作していないトリガーがある場合、同じパフォーマンス ヒットが発生する可能性があります。

于 2009-07-14T16:25:20.060 に答える