web-dev-qa-db-ja.com

キーとインデックスを含むサーバー間でテーブルをコピーする

私は約2週間小さなプロジェクトに取り組んできました。

ライブデータベースとは別にクエリとレポートを実行するために、いくつかのリモートサーバーデータベースのいくつかのテーブルを統合したい... DIYミニデータウェアハウスのようなものです。

3つのSQL Server 2008リモートサーバーがあり、3つの個別のSQL Server Express 2017インスタンスを実行する1つのローカルサーバーにデータをコンパイルしています。

SQL Server Expressデータベースがすべてセットアップされ、次のようないくつかの異なる方法を使用して、必要なテーブルのコピーをテストしました。

  • SSMSインポート/エクスポートウィザード
  • また、新しいデータベースのリンクサーバーを使用したスクリプト:

    INSERT INTO dbo.table
      SELECT *
      FROM remoteserver.remotedatabase.dbo.remotetable
    

これらは両方とも正常にコピーされたテーブルとデータですが、キー、インデックス、その他の制約ではありません。

私は最近データベースで作業しているだけなので、私は途方に暮れており、Googleは上記のコピーの提案を出しましたが、サーバー間でテーブルを転送するときに、キー、インデックス、その他の制約を含むものが見つかりません。

2
DaleP

特定のテーブルを選択的にスクリプト化する必要があるため、 dbatoolsを使用して、プログラムでテーブルやトリガーをスクリプト化できます などを使用して Export-DbaScript

または、 Export-DbaDacPackage -tableパラメータ付き。

リンクサーバーを使用しているため、私の回答 どちらがより効率的ですか:リンクサーバーから選択するか、リンクサーバーに挿入しますか? も役立ちます。

3
Kin Shah

そのため、当日​​は休みがあり、このアイデアに関していくつかの異なるテストに取り組んでいたため、少し反応がありませんでした。

要点をまとめると。目標は、データ、キー、インデックスなどを含む選択したテーブルを1つのリモートデータベースサーバーから別のリモートサーバーに同期して、レポート作成用の一種のDIYデータウェアハウスを形成することです。最後に、これは基本的に無料で私の時間を差し引いて行われます。

必要なテーブルにSSMSを使用してデータベースの最初のエクスポートを決定した後、データベースのスクリプト生成を行い、テーブルキー、インデックス、制約、および単純なデータベースデータエクスポートではキャプチャされなかった他のデータベース情報をキャプチャしました。 。

これにより、宛先サーバーのスペースを節約しながら、必要なテーブルのキー、インデックス、および制約がまだ残っているストリップされたデータセットが許可されました。

残念ながら無料はSQL Expressの使用を意味し、3つのインスタンスの1つが10GBのデータベースキャップに違反し、プロジェクトテストが無効になりました。

現在の選択肢は、SQLサーバーを購入するか、MySQLサーバーのデータ移行を利用するか、またはライブデータベースにクエリを実行することです(私の最初の選択肢ではありません。

みなさま、ありがとうございました。他に何もないのは、私が以前に持っていなかったSQL作業の非常に優れた味であり、一人ひとりのソリューションの提案を調査しました。皆さん、ありがとうございました。

0
DaleP

自分のサイトの1つでも同様のニーズがありました。メンテナンス期間中、毎晩、運用環境からレポートデータベースを作成する必要がありました。私はリンクサーバーを使用しませんでしたが、リモートサーバーにプライベートとインデックスおよびプライマリキーを追加する権限があると仮定すると、アプローチは同じように機能するはずです。データの読み込みステップの直後に、インデックスが存在しない場合は、create indexコマンドと主キーコマンドを実行します。

-- do the data loading
INSERT INTO dbo.table
  SELECT *
  FROM remoteserver.remotedatabase.dbo.remotetable;

-- create the indexes if they do not exist

if NOT exists ( select * FROM [remoteserver].[remotedatabase].[dbo].[sysindexes] where name = 'pk_remotetable' )

ALTER TABLE [remoteserver].[remotedatabase].[dbo].[remotetable] ADD  CONSTRAINT [pk_remotetable] PRIMARY KEY CLUSTERED ( [remotetable_ID] ASC );

go

if NOT exists ( select * FROM [remoteserver].[remotedatabase].[dbo].[sysindexes] where name = 'nc_index1' )

    CREATE NONCLUSTERED INDEX [nc_index1] ON [remoteserver].[remotedatabase].[dbo].[remotetable] (
    [col1] ASC) INCLUDE ( [col2], [col3])

go

データの読み込み時間を試して、インデックスを削除した方が速いかどうか、データの読み込みを行ってから再作成したり、データを読み込む前にインデックスを作成したりできます。インデックスが存在しない方がデータのロードが速いことがわかると思いますが、事後のインデックスの作成にはまだ時間がかかります。

たとえば、これを試すことができます

if exists ( select * FROM [remoteserver].[remotedatabase].[dbo].[sysindexes] where name = 'pk_remotetable' )

ALTER TABLE [remoteserver].[remotedatabase].[dbo].[remotetable] DROP CONSTRAINT [pk_remotetable]

go

if exists ( select * FROM [remoteserver].[remotedatabase].[dbo].[sysindexes] where name = 'nc_index1' )

DROP INDEX IX_index1 ON [remoteserver].[remotedatabase].[dbo].[remotetable]

go

次に、データをロードし、上記のようにpkおよびncインデックスを作成します。

注:私の場合、データのロードは(リンクサーバー経由ではなく)prodのバックアップを復元することによって行われたため、私の答えは少し理論的ですが、SQLエージェントジョブでは、OLTPデータベースは本番環境にありますが、レポートと、レポートに関連するインデックスの作成に集中しており、レポートの実行を高速化します。つまり、ソースデータベースに同じインデックスを自動的に再作成しますが、OLTPのニーズではなくレポートのニーズに特化して設計された新しいインデックスを宛先に作成します。

0
Jeff Mergler

個人的には、SSISを使用して、転送する必要があるアイテムの(特にデータベースを右クリックし、[タスク]、[スクリプトの生成]を選択して)作成スクリプトを生成します(特に、通常作成するのではなく、ドロップして再作成する必要がある場合、これにより、外部キーによって関連付けられたテーブルのシーケンス、操作されていないテーブルのFKの無効化/削除など、エラーを生成しない適切な順序で)、ターゲットDBで作成スクリプトを実行し、SSISデータポンプ操作を使用してデータを転送します。これは通常、システム間でデータを大量に転送する他の方法よりも高速です。

0
Laughing Vergil