2

より重要なプロジェクトの 1 つで、非常に大規模なデータベースを使用したいくつかのテスト セットでアプリケーションを実行する必要があります。通常の最大平均は約 100,000 エントリですが、約 18 ~ 24,000,000 エントリに対してテストしようとしています。

これで詳細に入ることができますが、大まかなレベルから質問する方がよいと思います。データをその規模で複製するための最良の方法は何ですか? 小さなセット (3 エントリ) を取得して、それを最大 18,000,000 まで複製する方が良いですか、それとも 100,000 レコードの既存のデータベースを取得して、それより少ない回数複製する必要がありますか?

各エントリの 1 つの列には一意の GUID を、別の列にはわかりやすい名前を付ける必要があるため、データを編集する必要があります。

元同僚のアーカイブからクリーンアップしたストアド プロシージャがあります。レコードを取得し、2 つの一意の列の末尾に増分番号を追加してから、閉じて再度実行します。6,000,000 に到達するのに約 4 時間かかり、それは約 14GB だと思います。最大 100,000 レコードまでしか使用していませんが、かなりうまく機能しています。

しかし、このサイズでは、ロックアップする (SQL Management Studio がクラッシュする) ように見えたり、非常に遅くなるか、何もせずにそのままのように動作します (CPU アクティビティがありません)。また、14GB のデータベース ファイルに対して 20GB のように、ログ ファイルは巨大になります。

現在のストアド プロシージャは次のとおりです。

USE [DBNAME]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[PERSON_Insert]
@LoopCount int,
@PersonId varchar(50)
AS 
BEGIN
DECLARE @intFlag INT ,@P_FIELD1 Varchar(50),@T_FIELD2 Varchar(10),@T_FIELD3 numeric(11,0), @T_FIELD4 numeric(11,0), @T_FIELD5 varchar(8000), @T_FIELD6 numeric(20,0)
,@TR_FIELD7 Varchar(10),@TR_FIELD8 numeric(11,0), @TR_FIELD9 numeric(11,0), @TR_FIELD10 varchar(8000), @TR_FIELD11 numeric(20,0)
    SET @intFlag = 1
select @P_FIELD1=dbo.MyRegistratonNo(@PersonId)
select @T_FIELD2=dbo.MyENGINETYPE(@PersonId,1)
select @T_FIELD3=dbo.MyTEMPLATEID(@PersonId,1)
select @T_FIELD4=dbo.MyTEMPLATETYPE(@PersonId,1)
select @T_FIELD5=dbo.MyTEMPLATEFEATURE(@PersonId,1)
select @T_FIELD6=dbo.MyTEMPLATESIZE(@PersonId,1)
select @TR_FIELD7=dbo.MyENGINETYPE(@PersonId,2)
select @TR_FIELD8=dbo.MyTEMPLATEID(@PersonId,2)
select @TR_FIELD9=dbo.MyTEMPLATETYPE(@PersonId,2)
select @TR_FIELD10=dbo.MyTEMPLATEFEATURE(@PersonId,2)
select @TR_FIELD11=dbo.MyTEMPLATESIZE(@PersonId,2)
WHILE (@intFlag <=@LoopCount)
BEGIN
INSERT INTO [PERSON]
([PERSONID],[REGISTRATIONNO] , [TYPEID] , [REGISTEREDDATE] , [STATUS])
VALUES(@PersonId+CAST(@intFlag AS varchar(50)),@P_FIELD1+CAST(@intFlag AS varchar(50)),1,GETDATE(),1)
INSERT INTO [TEMPLATES]
([PERSONID],[ENGINETYPE] , [TEMPLATEID] , [TEMPLATETYPE] , [TEMPLATEFEATURE] , [TEMPLATESIZE])
VALUES(@PersonId+CAST(@intFlag AS varchar(50)),@T_FIELD2,@T_FIELD3,@T_FIELD4,@T_FIELD5,@T_FIELD6)
INSERT INTO [TEMPLATES]
([PERSONID],[ENGINETYPE] , [TEMPLATEID] , [TEMPLATETYPE] , [TEMPLATEFEATURE] , [TEMPLATESIZE])
VALUES(@PersonId+CAST(@intFlag AS varchar(50)),@TR_FIELD7,@TR_FIELD8,@TR_FIELD9,@TR_FIELD10,@TR_FIELD11)
PRINT @P_FIELD1 +CAST(@intFlag AS varchar(50))
SET @intFlag = @intFlag + 1
END
END

いくつかのスカラー関数もあり、そのうちの 6 つが使用され、すべて同じ形式に従います。

USE [DBNAME]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[MyENGINETYPE]
(@PersonID varchar(50),@TemplateID numeric(11,0))
RETURNS varchar(10)
AS
BEGIN
DECLARE @Return varchar(10)
SELECT @Return = (SELECT ENGINETYPE FROM TEMPLATES WHERE PERSONID=@PersonID AND TEMPLATEID=@TemplateID)
RETURN @Return
END

私は軽いスクリプター/ウェブ開発者であり、実際にはデータベース管理者でも、このようなエンタープライズ クラスのデータが得意でもありません。そうは言っても、これは少なくともまともな方法ですか、それとも私はこのサーバーを何か不格好なもので殺害していますか? 私たちは SQL Server 2012 しか持っておらず、サードパーティ製のツールやそれに付属するもの以外のものは何も持っていません。そのままにしておきたいと思っています。

どんな例でも素晴らしいでしょう、事前に感謝します!!!

4

1 に答える 1

0

これにより、いくつかのアイデアが得られる場合があります。

SET NOCOUNT ON「挿入された1行」メッセージを停止することが重要です。

また、挿入の前にインデックスの無効化/削除を検討する価値があるかもしれません-物事をスピードアップするかもしれません。

CREATE TABLE Person
(
    PersonId UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY,
    Blah1 VARCHAR(50) DEFAULT REPLICATE('X', 50)
)
GO

SET NOCOUNT ON
GO

DECLARE @i INT
SET @i = 1

WHILE (@i <= 1000000)
BEGIN
   INSERT INTO Person DEFAULT VALUES 
   SET @i = @i + 1
END

もう 1 つのオプションは、フラット ファイルを作成し、一括挿入を使用することです。フラット ファイルの作成には多少の労力がかかる場合がありますが、データを変更する必要がない限り、1 回限りで作成する必要があります。

于 2012-06-25T21:01:16.623 に答える