私は非常に大規模なデータベース(〜100Gb)を持っており、主にサイズを縮小したい2つのテーブルで構成されています(どちらも約5,000万レコードあります)。同じスキーマを使用して、これら2つのテーブルを使用して同じサーバー上にアーカイブDBをセットアップしています。ライブデータベースから行を削除してアーカイブDBに挿入するための最良の概念的な方法を決定しようとしています。擬似コードでは、これは私が今していることです:
Declare @NextIDs Table(UniqueID)
Declare @twoYearsAgo = two years from today's date
Insert into @NextIDs
SELECT top 100 from myLargeTable Where myLargeTable.actionDate < twoYearsAgo
Insert into myArchiveTable
<fields>
SELECT <fields>
FROM myLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
DELETE MyLargeTable
FROM MyLargeTable INNER JOIN @NextIDs on myLargeTable.UniqueID = @NextIDs.UniqueID
現在、これは1000レコードを完了するのに恐ろしく遅い7分かかります。削除と挿入をテストしましたが、どちらも約1時間かかります。完了するまでに3.5分かかるため、必ずしも一方が他方よりも大幅に非効率的であるとは限りません。誰かがこれでいくつかの最適化のアイデアを指摘できますか?
ありがとう!
これはSQLServer2000です。
編集:大きなテーブルでは、ActionDateフィールドにクラスター化されたインデックスがあります。他に2つのインデックスがありますが、どちらもどのクエリでも参照されていません。アーカイブテーブルにはインデックスがありません。私のテストサーバーでは、これがSQL Serverにヒットする唯一のクエリであるため、十分な処理能力が必要です。
コード(これは一度に1000レコードのバッチでループを実行します):
DECLARE @NextIDs TABLE(UniqueID int primary key)
DECLARE @TwoYearsAgo datetime
SELECT @TwoYearsAgo = DATEADD(d, (-2 * 365), GetDate())
WHILE EXISTS(SELECT TOP 1 UserName FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [ActionDateTime] < @TwoYearsAgo)
BEGIN
BEGIN TRAN
--get all records to be archived
INSERT INTO @NextIDs(UniqueID)
SELECT TOP 1000 UniqueID FROM [ISAdminDB].[dbo].[UserUnitAudit] WHERE [UserUnitAudit].[ActionDateTime] < @TwoYearsAgo
--insert into archive table
INSERT INTO [ISArchive].[dbo].[userunitaudit]
(<Fields>)
SELECT <Fields>
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
--remove from Admin DB
DELETE [ISAdminDB].[dbo].[UserUnitAudit]
FROM [ISAdminDB].[dbo].[UserUnitAudit] AS a
INNER JOIN @NextIDs AS b ON a.UniqueID = b.UniqueID
DELETE FROM @NextIDs
COMMIT
END