1

テーブルに大量のレコードを挿入しようとしています。これはシナリオです:

  1. SQL Server 2008 (DB は 2005 年)

  2. 宛先テーブルにはクラスター化インデックス (PK) があります。このフィールドは ID である必要がありますが、DB の開発者 (プログラムに影響するため変更できませんでした) は、整数として作成します。プログラムがテーブルに行を追加する必要があるたびに、最大 ID (historynoこの場合) を見て、1 を合計します。

  3. これは、同時に多数のレコードを挿入する必要がある場合のパフォーマンスに影響するため、一時テーブル ( AKT_ES_CampTool_TempHist) から行を挿入するプロセスを生産時間外に作成します。

  4. 問題は、1 時間で 8K 行しか挿入されないことです。120K 以上を挿入する必要があることを考えると、時間がなくなります。

使用するコードは次のとおりです。誰かがそれを改善するためのアイデアを持っていれば、それはありがたいです。

DECLARE             @HistNo         AS INT

WHILE EXISTS (SELECT * FROM AKT_ES_CampTool_TempHist WHERE Inserted = 0)
BEGIN

    SELECT  @HistNo=MIN(HistoryNo) FROM AKT_ES_CampTool_TempHist WHERE Inserted = 0

    INSERT INTO NOVADB.dbo.niHist   (
        HistoryNo,ObjectType,ObjectNo,SubNo,ReferenceNo, 
        Time,Type,Priority,Collector,Code,
        Action,RemainingAmount,Obliterated,SubType,ActSegment,
        Data,FreetextData,quantity
                                        )
        SELECT      
        (SELECT  max(historyNo)+1 
        FROM    NOVADB..niHist),ObjectType,ObjectNo,SubNo,ReferenceNo,
        Time,Type,Priority,Collector,Code,
        Action,RemainingAmount,Obliterated,SubType,ActSegment,
        Data,FreetextData,quantity 
        FROM        AKT_ES_CampTool_TempHist 
        WHERE       HistoryNo=@HistNo

        UPDATE  AKT_ES_CampTool_TempHist
        SET     Inserted=1
        WHERE   HistoryNo=@HistNo

END
4

3 に答える 3

2

明らかに適切な答えは、その historyNo 列を ID に変更することですが、それができないため、セット全体で ROW_NUMBER を使用して増分番号を取得し、前の最大 historyNo に追加してみませんか?

次に、挿入を次のように変更できます

DECLARE  @OldMaxHistNo  AS INT
SELECT @OldMaxHistNo = MAX(historyNo) FROM NOVADB..niHist

INSERT INTO NOVADB.dbo.niHist   (
    HistoryNo,ObjectType,ObjectNo,SubNo,ReferenceNo, 
    Time,Type,Priority,Collector,Code,
    Action,RemainingAmount,Obliterated,SubType,ActSegment,
    Data,FreetextData,quantity
                                    )
    SELECT      
    @OldMaxHistNo+ ROW_NUMBER() OVER(ORDER BY ObjectNo)
    FROM    NOVADB..niHist),ObjectType,ObjectNo,SubNo,ReferenceNo,
    Time,Type,Priority,Collector,Code,
    Action,RemainingAmount,Obliterated,SubType,ActSegment,
    Data,FreetextData,quantity 
    FROM        AKT_ES_CampTool_TempHist 
    WHERE       Inserted = 0

    UPDATE  AKT_ES_CampTool_TempHist
    SET     Inserted=1

ただし、実行中にトランザクション内でテーブルをロックする必要がある場合があります

于 2013-09-25T11:11:58.730 に答える