由于活动事务,SQL Server日志已满

时间:2018-11-05 04:03:55

标签: sql-server tsql transaction-log

我一直在尝试更新表中的列,但出现以下错误:

 The transaction log for database 'STAGING' is full due to 'ACTIVE_TRANSACTION'.

我正在尝试运行以下语句:

UPDATE [STAGING].[dbo].[Stg_Encounter_Alias]
    SET
        [valid_flag]            = 1

    FROM  [Stg_Encounter_Alias] Stg_ea
    where [ACTIVE_IND] = 1
        and [END_EFFECTIVE_DT_TM] > convert(date,GETDATE())

我的表大约有1800万行。上面的更新将修改所有行。表格大小为2.5 GB。数据库也处于简单恢复模式

这是我将经常在不同的表上执行的操作。我该如何处理?

我的数据库大小如下

enter image description here

以下是数据库属性!!!我尝试将日志大小更改为无限制,但它又恢复为默认值。

enter image description here

有人可以告诉我一种有效的方法来处理这种情况吗?

如果我批量运行:

begin
DECLARE @COUNT INT
SET @COUNT = 0

SET NOCOUNT ON;      
DECLARE @Rows INT,
    @BatchSize INT; -- keep below 5000 to be safe

SET @BatchSize = 2000;

SET @Rows = @BatchSize; -- initialize just to enter the loop


WHILE (@Rows = @BatchSize)
BEGIN
  UPDATE TOP (@BatchSize) [STAGING].[dbo].[Stg_Encounter_Alias]
    SET
        [valid_flag]            = 1

    FROM  [Stg_Encounter_Alias] Stg_ea
    where [ACTIVE_IND] = 1
        and [END_EFFECTIVE_DT_TM] > convert(date,GETDATE())
  SET @Rows = @@ROWCOUNT;
END;
end

2 个答案:

答案 0 :(得分:3)

您正在单个事务中执行更新,这会导致事务日志变得非常大。

相反,请批量执行更新,例如一次执行50K-100K。

您在END_EFFECTIVE_DT_TM上有一个包含ACTIVE_INDvalid_flag的索引吗?这将有助于提高性能。

CREATE INDEX NC_Stg_Encounter_Alias_END_EFFECTIVE_DT_TM_I_ 
ON [dbo].[Stg_Encounter_Alias](END_EFFECTIVE_DT_TM) 
INCLUDE (valid_flag) 
WHERE ([ACTIVE_IND] = 1);

如果您正在运行Enterprise Edition或SQL Server 2016 SP1或更高版本(任何版本),则可以极大地提高性能的另一件事是为表及其索引打开data_compression = page

答案 1 :(得分:0)

感谢您对米奇的帮助。实际上,我已经增加了事务日志的大小,并删除了所有索引作为其登台数据库。并在24秒内更新了1,700万行:)

尽管我对解决方案不是很满意,但是由于时间不足,我将继续进行下去。我将不得不进一步提高效率。