2016-05-05 3 views
1

私はこれをスピードアップする方法を考えることができません。テーブルスキャンをしていますが、私はすべてのレコードを更新する必要があるからです。この単純なクエリのパフォーマンスを向上させる方法はありますか?

問題は、このテーブルには約3,000万のレコードがあることです。

実行には約50分かかります。誰でも私はこれを改善する方法についてのヒントがありますか?それはどこにも使用されていないので、

update A 
    set  A.product_dollar_amt = round(A.product_dollar_amt, 2), 
      A.product_local_amt = round(A.product_local_amt, 2), 
      A.product_trans_amt = round(A.product_trans_amt, 2) 
    from dbo.table A 

テーブルには、現在、ヒープ(クラスタ化インデックスなし)です...ではないクラスタ化インデックスを作成すると、ここで何を改善するか確認します。

+0

更新をバッチで行うのはどうですか? –

+0

どうしたら違うのですか? –

+0

sp_WhoIsActiveを使用してクエリを監視し、異常な待機が発生していないかどうかを確認できます。また、この結果を_different_表にロードして名前を変更することもできます(または別のスキーマに移動することもできます)。その後、変更は瞬時に行われるように見えますが、3,000万レコードで2つのテーブルを格納する必要があります。 –

答えて

2

本当にここには何もありません。あなたはすべての単一の行を更新しており、それはそれがかかる限り長くかかるでしょう。 1回のトランザクションで30Mの行を更新するのは良い考えではありませんが、私はあなたに話すことができます。あなたは簡単にあなたのトランザクションログを吹き飛ばすことができます。また、このテーブルが他のユーザによって使用されている場合は、テーブル全体が更新されるまでそれらをすべてロックすることになります。この表を小規模なバッチで更新するほうがはるかに優れています。全体的なパフォーマンスは改善されませんが、トランスログや他のユーザーにはほとんど負担がかかりません。

3

ここには3つのオプションがあります。

ランディが最初に言及したのは、作業をバッチで行うことです。

第2の方法は、一時テーブルに結果をダンプし、元のテーブルを再作成することです:

select . . . , 
     product_dollar_amt = round(A.product_dollar_amt, 2), 
     product_local_amt = round(A.product_local_amt, 2), 
     product_trans_amt = round(A.product_trans_amt, 2) 
into a_temp 
from a; 

drop a; 

sp_rename 'a_temp', 'a'; 

注:これは、それは、より高速であることが保証はなく、ログの挿入、更新をログに記録するよりも速くなっているためされていませんよくあることです。また、索引やトリガーを再構築する必要があります。

最後に、「非更新」ソリューションがあります:代わりに得られた値を作成します。

sp_rename 'A.product_dollar_amt', '_product_dollar_amount', 'COLUMN'; 
sp_rename 'A.product_local_amt', '_product_local_amt', 'COLUMN'; 
sp_rename 'A.product_trans_amt', '_product_trans_amt', 'COLUMN'; 

を次に式として、背面の列を追加します。

alter table A add product_dollar_amt as (round(product_dollar_amt, 2)); 
alter table A add product_local_amt = round(product_local_amt, 2); 
alter table A add product_trans_amt = round(product_trans_amt, 2); 
0
  1. を使用して更新を並列化オプションやヒントを使用してクエリを実行することができます。
  2. 利用できない場合は、更新セッションを同時に実行して別々に作業を分割することができます。これにより、作業を効率的に分割することができます(パーティションを使用することが望ましい)。
  3. インデックスの無効化/削除、ポイント・イン・タイム・リカバリを可能にするトランザクション・ロギングの無効化などの場合は、インデックス化された列を更新したり、新しい行を追加したりしても、

    理論的には16コアシステム(CPUアーキテクチャで利用可能なハイパースレッド用のx2)。他のボトルネック(ディスクio)がない場合、50分のジョブは3分で実行されます。

関連する問題