10

I am implementing an A/B/View scenario, meaning that the View points to table A, while table B is updated, then a switch occurs and the view points to table B while table A is loaded.

The switch occurs daily. There are millions of rows to update and thousands of users looking at the view. I am on SQL Server 2012.

My questions are:

  • 可能な限り最速の方法で別のテーブルからテーブルにデータを挿入するにはどうすればよいですか? (ストアド プロシージャ内)
  • BULK INSERT を使用する方法はありますか? または、通常の挿入/選択を使用するのが最速の方法ですか?
4

6 に答える 6

2

ColA、ColBをSrcTableからDestTable_Newに選択できます。DestTable_Newがロードされたら、インデックスと制約を再作成します。

次に、DestTableの名前をDestTable_Oldに変更し、DestTable_Newの名前をDestTableに変更します。名前の変更は非常に迅速です。何かがうまくいかなかったことが判明した場合は、(DestTable_Old)の近くにある前のテーブルのバックアップもあります。

このシナリオは、システムを24時間年中無休で実行し、毎日数千万行をロードする必要がある場合に一度実行しました。

于 2012-06-19T12:33:45.263 に答える
2

私はSSISを使用する傾向があります。

テーブル A を OLEDB ソースに、テーブル B を OLEDB 宛先にします。トランザクション ログをバイパスするため、DB の負荷を軽減します。T-SQL を使用してこれを行う唯一の方法 (私が考えることができる) は、データベース全体の復旧モデルを変更することです。これは、転送用のトランザクションだけでなく、トランザクションが保存されないことを意味するため、理想とはほど遠いものです。

SSIS 転送の設定

新しいプロジェクトを作成し、データフロー タスクをデザイン サーフェイスにドラッグする

ツールボックスメニュー

データフロー タスクをダブルクリックすると、[データ フロー] タブに移動します。次に、[データ フローのソース] メニューから OLE DB ソースをドラッグ アンド ドロップし、[データ フローの宛先] メニューから OLE DB の宛先をドラッグ アンド ドロップします。

データ フロー ソースデータ フローの宛先

OLE DB ソースをダブルクリックし、サーバーへの接続を設定し、ロード元のテーブルを選択して [OK] をクリックします。緑の矢印を OLE DB ソースから宛先にドラッグし、宛先をダブルクリックします。接続マネージャー、宛先テーブル名、および列マッピングを設定すれば、準備完了です。

MSDN の OLE DB ソース ドキュメント

MSDN の OLE DB Destination ドキュメント

于 2012-06-19T12:20:20.513 に答える
2

あなたはできる

SELECT fieldnames
INTO DestinationTable
FROM SourceTable

いくつかの回答が示唆しているように、それは可能な限り高速である必要があります(再作成する必要があるインデックスの数などによって異なります)。

ただし、ポインターをあるテーブルから別のテーブルに変更するには、同義語を使用することをお勧めします。それらは非常に透過的であり、私の意見では、ビューを更新したり、テーブルの名前を変更したりするよりもクリーンです。

于 2012-06-19T14:54:56.053 に答える
1

質問が古いことは知っていますが、同じ質問に対する答えを探していて、本当に役立つものは何も見つかりませんでした. はい、SSISアプローチは可能ですが、質問にはストアドプロシージャが必要でした。

嬉しいことに、元の質問が望んでいた解決策を (ほぼ) 発見しました。CLR SPでそれを行うことができます。

TableA から DataTable にデータを選択し、DestinationTableName として TableB を指定して SqlBulkCopy クラスの WriteToServer(DataTable dt) メソッドを使用します。

唯一のわずかな欠点は、CLR プロシージャが SqlBulkCopy を使用するために外部アクセスを使用する必要があり、コンテキスト接続では機能しないことです。そのため、アクセス許可と接続文字列を少しいじる必要があります。しかしねえ!何も完璧ではありません。

于 2016-07-26T06:39:17.470 に答える
0

INSERT... SELECT...とほぼ同じように機能しますBULK INSERT。@GarethDが言うように、SSISを使用できますが、テーブル1からテーブル2に行をコピーするだけの場合、それは非常に複雑になる可能性があります.

かなりの量のデータをコピーする場合は、トランザクション ログに注意してください。大量の挿入を行うと、トランザクション ログが急速に肥大化する可能性があります。回避策の 1 つは、たとえば一度に 100,000 行または 10,000 行のみを処理する挿入ステートメントをループすることによって、挿入するデータを「チャンク化」することです (行の幅、つまりパスあたりの MB 数によって異なります)。

(ちょっと興味がありますALTER VIEW。ビューをリセットしようとしているのですか?過去/現在/次/スワップ セットをサポートするために 4 つのテーブルと 4 つのビューが必要でしたが、私は一度似たようなことをしました。)

于 2012-06-19T13:18:52.820 に答える
0

あなたは単にこのようにすることができます

    select * into A from B Where [criteria]

これにより、条件に基づいて B からデータが選択され、列が同じであるか、* の代わりに列名を指定できる場合、A に挿入されます。

于 2012-06-19T13:24:47.857 に答える