【问题标题】:Run large compare in Batches批量运行大比较
【发布时间】:2017-05-02 18:29:29
【问题描述】:

我需要比较具有数百万行的大型表并将差异插入到日志表中。

问题是存储过程增长(LDF),并且数据库磁盘空间有限。

我知道提交会将 LDF 写入 MDF。

如何分批执行以下比较,每十万行提交一次?

BEGIN TRY
BEGIN TRANSACTION;


            INSERT  INTO dbo.CustomerLog
                    ( OnlineStore ,
                      PhoneNumber ,
                      ChangeType
                    )
                    SELECT  'Online Store a' ,
                            AreaCode + PhoneNumber ,
                            'Added'
                    FROM    dbo.StoreAList a
                    WHERE   NOT EXISTS ( SELECT 1
                                         FROM   dbo.StoreAListCompare b
                                         WHERE  ( b.AreaCode + b.PhoneNumber ) = ( a.AreaCode
                                                              + a.PhoneNumber ) );

COMMIT TRANSACTION                          
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION    
END CATCH;




CREATE TABLE [dbo].[StoreAList](
    [ListID] [bigint] IDENTITY(1,1) NOT NULL,
    [AreaCode] [char](3) NOT NULL,
    [PhoneNumber] [char](7) NOT NULL,
    [RecordDate] [datetime] NULL CONSTRAINT [DF_StoreAList_RecordDate]  DEFAULT (getdate())
) ON [PRIMARY]


CREATE TABLE [dnc].[StoreAListCompare](
    [ListID] [BIGINT] IDENTITY(1,1) NOT NULL,
    [AreaCode] [CHAR](3) NOT NULL,
    [PhoneNumber] [CHAR](7) NOT NULL,
    [RecordDate] [DATETIME] NULL DEFAULT (GETDATE())
) ON [PRIMARY]

【问题讨论】:

  • 旁白:如果您使用包含AreaCodePhoneNumber 的每个表的单个 索引为StoreAListStoreAListCompare 编制索引,只是对性能变化感到好奇,然后更改 where 以分别比较字段。
  • 是的,它们确实有索引,但问题是日志,而不是性能

标签: sql tsql sql-server-2014


【解决方案1】:

您可以使用@@rowcount 系统变量并批量插入,直到@@rowcount 达到0。

注意在 dbo.CustomerLog 中添加的 AND NOT EXISTS...

例如:

DECLARE @BATCHSIZE INT=100000

WHILE @BATCHSIZE>0
BEGIN
    BEGIN TRY
    BEGIN TRANSACTION;


                INSERT  INTO dbo.CustomerLog
                        ( OnlineStore ,
                          PhoneNumber ,
                          ChangeType
                        )
                        SELECT  TOP(@BATCHSIZE) 
                                'Online Store a' ,
                                AreaCode + PhoneNumber ,
                                'Added'
                        FROM    dbo.StoreAList a
                        WHERE   NOT EXISTS ( SELECT 1
                                             FROM   dbo.StoreAListCompare b
                                             WHERE  ( b.AreaCode + b.PhoneNumber ) = ( a.AreaCode + a.PhoneNumber ) )
                        AND NOT EXISTS (SELECT 1 
                                        FROM dbo.CustomerLog CL
                                        WHERE 'Online Store a'=CL.OnlineStore
                                        AND AreaCode + PhoneNumber=CL.PhoneNumber
                                        AND 'Added'=CL.ChangeType);

                        SET @BATCHSIZE=@@ROWCOUNT

    COMMIT TRANSACTION                          
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION
        SET @BATCHSIZE=0  
    END CATCH;
END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2019-11-09
    • 1970-01-01
    相关资源
    最近更新 更多