現在の年を除くすべてをアーカイブし、同時にテーブルをパーティション分割する最良の方法は何ですか


23

仕事

大きなテーブルのグループから、13か月のローリング期間を除くすべてをアーカイブします。アーカイブされたデータは別のデータベースに保存する必要があります。

  • データベースは単純復旧モードです
  • テーブルは50ミリ行から数十億行で、場合によってはそれぞれ数百GBを占有します。
  • テーブルは現在パーティション化されていません
  • 各テーブルには、増え続ける日付列に1つのクラスター化インデックスがあります
  • 各テーブルには、さらに1つの非クラスター化インデックスがあります
  • テーブルに対するすべてのデータ変更は挿入です
  • 目標は、プライマリデータベースのダウンタイムを最小限に抑えることです。
  • サーバーは2008 R2 Enterpriseです

「アーカイブ」テーブルには約11億行、「ライブ」テーブルには約4億行が含まれます。明らかに、アーカイブテーブルは時間とともに増加しますが、ライブテーブルも合理的に急速に増加することを期待しています。少なくとも次の数年で50%と言います。

Azureストレッチデータベースについて考えていましたが、残念ながら2008 R2にあり、しばらくそこに留まる可能性があります。

現在の計画

  • 新しいデータベースを作成する
  • 新しいデータベースに(変更日を使用して)月ごとにパーティション分割された新しいテーブルを作成します。
  • 直近の12〜13か月分のデータをパーティションテーブルに移動します。
  • 2つのデータベースの名前変更スワップを行う
  • 移動したデータを現在の「アーカイブ」データベースから削除します。
  • 「アーカイブ」データベースの各テーブルをパーティション分割します。
  • パーティションスワップを使用して、将来データをアーカイブします。
    • アーカイブするデータをスワップアウトし、そのテーブルをアーカイブデータベースにコピーし、それをアーカイブテーブルにスワップする必要があることを理解しています。これは許容範囲です。

問題: データを初期パーティションテーブルに移動しようとしています(実際、まだデータの概念実証を行っています)。私はTF 610(データロードパフォーマンスガイドに従って)とINSERT...SELECTステートメントを使用して、データを最小限に記録されると最初に考えて移動しようとしています。残念ながら、私が試すたびに完全にログに記録されます。

この時点で、SSISパッケージを使用してデータを移動することが最善の策だと考えています。200個のテーブルと、スクリプトでできることはすべて簡単に生成して実行できるため、これを回避しようとしています。

私の一般的な計画で不足しているものはありますか?SSISは、ログを最小限に抑えてデータをすばやく移動するための最善の策です(スペースの問題)?

データなしのデモコード

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
); 
-- ~1.4 bill rows, ~20% in the last year

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(   [Modified] ASC   )
GO


-- New DB & Code
USE Audit_New
GO

CREATE PARTITION FUNCTION ThirteenMonthPartFunction (datetime)
AS RANGE RIGHT FOR VALUES ('20150701', '20150801', '20150901', '20151001', '20151101', '20151201', 
                            '20160101', '20160201', '20160301', '20160401', '20160501', '20160601', 
                            '20160701') 

CREATE PARTITION SCHEME ThirteenMonthPartScheme AS PARTITION ThirteenMonthPartFunction
ALL TO ( [PRIMARY] );

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] NULL,
    [Col6] [money] NULL,
    [Modified] [datetime] NULL,
    [ModifiedBy] [varchar](50) NULL,
    [ModifiedType] [char](1) NULL
) ON ThirteenMonthPartScheme (Modified)
GO

CREATE CLUSTERED INDEX [AuditTable_Modified] ON [dbo].[AuditTable]
(
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

CREATE NONCLUSTERED INDEX [AuditTable_Col1_Col2_Col3_Col4_Modified] ON [dbo].[AuditTable]
(
    [Col1] ASC,
    [Col2] ASC,
    [Col3] ASC,
    [Col4] ASC,
    [Modified] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON ThirteenMonthPartScheme (Modified)
GO

コードを移動

USE Audit_New
GO
DBCC TRACEON(610);

INSERT INTO AuditTable
SELECT * FROM Audit.dbo.AuditTable
WHERE Modified >= '6/1/2015'
ORDER BY Modified

REは、「データを移動」:あなたがバッチなどで「Approch 2」のデータを移動することができ、ログの使用量を最小限にするためにdba.stackexchange.com/a/139009/94130。パーティション分割に関して、パーティション分割ビューを検討しましたか?
アレックス

@Alex Yea、私はそれらの両方を検討しました。私のバックアップ計画は、SSISを使用してバッチでデータを移動することです。そして、この特定のケースの場合、私の問題はまさにパーティション化の目的です。(スイッチングを使用したデータの迅速なロード/アンロード)
ケネスフィッシャー

回答:


10

最小限のログを取得できないのはなぜですか?

参照しているデータ読み込みパフォーマンスガイドは非常に貴重なリソースであることがわかりました。ただし、100%包括的ではなくTable Partitioning、挿入を受け取るテーブルがパーティション化されているかどうかに応じて、著者が動作の違いを解消する列を追加しなかったため、グリッドは既に十分に複雑であると思われます。後で見るように、テーブルがすでにパーティション化されているという事実は、最小限のロギングを禁止しているように見えます。

ここに画像の説明を入力してください

推奨されるアプローチ

データロードパフォーマンスガイド(「パーティションテーブルの一括ロード」セクションを含む)の推奨事項と、数百億行のパーティションテーブルのロードに関する豊富な経験に基づいて、以下の方法をお勧めします。

  • 新しいデータベースを作成します。
  • 新しいデータベースに月ごとにパーティション分割された新しいテーブルを作成します。
  • 次の方法で、最新の年のデータを移動します。
    • 毎月、新しいヒープテーブルを作成します。
    • TABLOCKヒントを使用して、その月のデータをヒープに挿入します。
    • その月のデータを含むヒープにクラスター化インデックスを追加します。
    • テーブルに今月のデータのみが含まれるように強制するチェック制約を追加します。
    • テーブルを、新しい全体的なパーティションテーブルの対応するパーティションに切り替えます。
  • 2つのデータベースの名前変更スワップを実行します。
  • 現在「アーカイブ」されているデータベースのデータを切り捨てます。
  • 「アーカイブ」データベースの各テーブルをパーティション分割します。
  • パーティションスワップを使用して、将来データをアーカイブします。

元のアプローチと比較した場合の違い:

  • TABLOCKパーティションスイッチングを使用してデータをパーティションテーブルに配置し、一度に1か月ずつヒープに読み込むと、最近の12〜13か月のデータを移動する方法がより効率的になります。
  • DELETE古いテーブルを消去するためのA は完全にログに記録されます。おそらくTRUNCATE、テーブルを削除するか、テーブルを削除して、新しいアーカイブテーブルを作成できます。

近年のデータを移動するためのアプローチの比較

マシン上で妥当な時間内にアプローチを比較するために、100MM row生成し、スキーマに従っているテストデータセットを使用しました。

以下の結果からわかるように、TABLOCKヒントを使用してヒープにデータをロードすることにより、ログ書き込みのパフォーマンスが大幅に向上および低下します。これが一度に1つのパーティションで実行される場合、追加の利点があります。また、一度に複数のパーティションを実行する場合は、一度に1パーティションずつメソッドを簡単に並列化できることにも注意してください。ハードウェアにもよりますが、それによって良い結果が得られる場合があります。通常、サーバークラスのハードウェアに少なくとも4つのパーティションを一度に読み込みます。

ここに画像の説明を入力してください

完全なテストスクリプトを次に示します

最終ノート

これらの結果はすべて、ある程度ハードウェアに依存します。ただし、私のテストは、回転ディスクドライブを搭載した標準のクアッドコアラップトップで実施されました。このプロセスを実行しているときに他の負荷があまりないまともなサーバーを使用している場合、データの読み込みははるかに高速になるはずです。

たとえば、実際の開発サーバー(Dell R720)で推奨アプローチを実行し、76 seconds156 seconds私のラップトップから)に削減されたことがわかりました。興味深いことに、パーティション化されたテーブルに挿入する元のアプローチでは同じ改善は行われず12 minutes、開発サーバーで引き継がれました。おそらくこれは、このパターンがシリアル実行プランを生成し、ラップトップ上の単一のプロセッサーが開発サーバー上の単一のプロセッサーと一致する可能性があるためです。


再びジェフに感謝します。SWITCHメソッドを使用しています。具体的には、SSISと動的SQLを使用して、13か月を並行して実行しています。
ケネスフィッシャー

1

これは、Bimlの良い候補かもしれません。1つのアプローチは、For Eachコンテナを使用して、小さな日付範囲の単一テーブルのデータを移行する再利用可能なテンプレートを作成することです。Bimlは、テーブルコレクションをループして、各修飾テーブルに同一のパッケージを作成します。アンディ・レナードは階段シリーズにイントロを持っています。


0

新しいデータベースを作成する代わりに、実際のデータベースを新しいデータベースに復元し、最新の12〜13か月のデータを削除することもできます。次に、実際のデータベースで、作成したばかりのアーカイブ領域に含まれていないデータを削除します。大量の削除が問題になる場合は、スクリプトを使用して10K以上のセットを削除するだけで済みます。

パーティショニングタスクは、削除された後、どちらのデータベースにも干渉されないように見え、どちらのデータベースにも適用できるようです。


私は以前に小さなデータベースでそれをやったことがあります。現在のサイズと、両側にパーティションテーブルを作成したいという事実を考えると、この方法では実際に時間がかかり、かなり多くのスペースが必要になると思います(最小で現在のDBサイズの2倍)
ケネスフィッシャー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.