2017-02-12 10 views
2

I 900万件のレコードを持つデータベースのテーブルを持っています。私は、それらをディメンションに参加させ、ファクトテーブルのキーをディメンションのキーに設定することによって、そのテーブルの4つの異なるキーを更新する必要がある状況にあります。私は4つの異なるSQLスクリプト(下記の例を参照)を書いて更新を行っていますが、実行には時間がかかりすぎてしまうという問題があります。クエリは20時間以上実行されており、どのくらいの時間がかかるか、またどれくらいかかるかについてはわかりません。これを改善するための方法はありますか?完了までに数時間しかかかりません。インデックスを追加するとこれが改善されますか?SQL - 大規模なテーブルの更新クエリのパフォーマンス(9億)レコード

UPDATE f 
SET f.ClientKey = c.ClientKey 
FROM dbo.FactSales f 
JOIN dbo.DimClient c 
ON f.ClientId = c.ClientId 
+1

あなたは900,000,000行のテーブルに対してこれを実行する前に、小さなサブセットにテストしていませんか?ああ。最悪の場合は、更新された列のインデックスになります。私は新しいテーブルを作成し、その中に4つのすべての結合を持つ単一のSelectを作成し、挿入/選択、ドロップ&名前を変更することを好みます。 – dnoeth

+0

@DuduMarkovitzが正しい –

答えて

0
  1. スクリプト外部キー。それらを落とす。
  2. 更新された列のスクリプトインデックス(条件の一部ではありません)。それらを落とす。
  3. 存在する場合はトリガーを無効にします。
  4. ロックを作成できるすべてのプロセスを無効にします(= all、includeを選択)。
  5. キーを更新します。
  6. 外部キー、インデックス、トリガーを再作成します。
  7. 喜んでください。

5のコメント - すべての新しいソースコードのみで目的地テーブルからプライマリキーを準備し、1つのステートメントを実行します。これは、ジョインに要するコストが低く、ジョインが1つだけになることを意味します。

0

あなたは4つの異なるキーを更新する必要がある場合

select 1 
while(@@rowcount > 0) 
begin 
    UPDATE f 
    SET top (100000) f.ClientKey = c.ClientKey 
    FROM dbo.FactSales f 
    JOIN dbo.DimClient c 
    ON f.ClientId = c.ClientId 
    AND f.ClientKey != c.ClientKey 
end 

トランザクションログをいっぱいにしないようにこれを使用することができ、その後一度にすべてを行う
コストの大部分がロック

無効にFを取得しています.ClientKeyを実行して更新を実行してから再構築してください

DimClientがwith (nolock)に変更されないことが確実だと確信がある場合は、必ず

FactSalesを更新する必要がある唯一のプロセスであれば、タブロックロックを取る

+0

...これは痛い...ロールバックしようとしている(「」またはそれ以上の可能性が高い)の場合。トランザクションログをいっぱいにして、すべてが改善されましたか? –

+0

...あなたは何度も何度も何度も何度と何度も何度もデータをスキャンしようとしている – Paparazzi

+0

私はあなたの意図を得ていません –

0

正しい値で新しいテーブルを作成します。インデックス、制約を後で追加します。可能であれば、既存のテーブルを削除し、新しいテーブルの名前を1つのトランザクションで既存のテーブルに変更します。

関連する問題