Sql-Server

無法執行 SELECT COUNT(*),表上的行數超過 10 億

  • January 17, 2019

我有這個包含超過十億行的表並發出查詢,我發出:

SELECT
  Total_Rows= SUM(st.row_count)
FROM
  sys.dm_db_partition_stats st
WHERE
   object_name(object_id) = 'audit_tb' AND (index_id < 2)

Output:
1055075195

我被要求在 2014 年刪除記錄,以便進行測試,我嘗試在 2014 年刪除最後 3 個月,已經超過 1 小時,它仍在執行,有什麼想法嗎?我懷疑有壞行。

DELETE 
 FROM [audit_tb]
 where datetime >= '2014-01-01 00:00:00' 
 AND datetime <= '2014-03-31 00:00:00' --3 months in 2014

該表還有一個 CLUSTERED INDEX。

這是一個分塊刪除的腳本。它刪除 4500 條記錄的塊以避免鎖升級。它執行 100 次循環以刪除總共 450,000 行。如果您的數據庫正在使用 FULL 恢復模型,您可能希望在每次執行備份份事務日誌以防止變得太大。

SET NOCOUNT ON;
DECLARE @continue INT
DECLARE @rowcount INT
DECLARE @loopCount INT
DECLARE @MaxLoops INT
DECLARE @TotalRows BIGINT
DECLARE @PurgeBeginDate DATETIME
DECLARE @PurgeEndDate DATETIME

SET @PurgeBeginDate = '2014-01-01 00:00:00'
SET @PurgeEndDate = '2014-03-31 23:59:59'

SET @MaxLoops = 100
SET @continue = 1
SET @loopCount = 0

SELECT @TotalRows = (SELECT COUNT(*) FROM audit_tb (NOLOCK) WHERE datetime between @PurgeBeginDate and @PurgeEndDate)
PRINT 'Total Rows = ' + CAST(@TotalRows AS VARCHAR(20))
PRINT ''

WHILE @continue = 1 
BEGIN
   SET @loopCount = @loopCount + 1
   PRINT 'Loop # ' + CAST(@loopCount AS VARCHAR(10))
   PRINT CONVERT(VARCHAR(20), GETDATE(), 120)

   BEGIN TRANSACTION
       DELETE TOP (4500) audit_tb WHERE datetime between @PurgeBeginDate and @PurgeEndDate
       SET @rowcount = @@rowcount 
   COMMIT

   PRINT 'Rows Deleted: ' + CAST(@rowcount AS VARCHAR(10))
   PRINT CONVERT(VARCHAR(20), GETDATE(), 120)
   PRINT ''

   IF @rowcount = 0 OR @loopCount >= @MaxLoops
   BEGIN
       SET @continue = 0
   END
END

SELECT @TotalRows = (SELECT COUNT(*) FROM audit_tb (NOLOCK) WHERE datetime between @PurgeBeginDate and @PurgeEndDate)
PRINT 'Total Rows Remaining = ' + CAST(@TotalRows AS VARCHAR(20))
PRINT ''


GO

我在 SQL 代理作業中使用它來重複執行,直到刪除所需的行數。我只是安排作業每 15 分鐘執行一次,因此我的 tran 日誌備份作業在此作業的執行之間執行。

我希望這有幫助

select 1 
while (@@rowcount > 0)
begin 
 DELETE top (100000) 
 FROM [audit_tb]
 where datetime >= '2014-01-01 00:00:00' 
   AND datetime <  '2015-01-01 00:00:00' 
end

您可以調整 100000 但這是​​一個很好的起點

引用自:https://dba.stackexchange.com/questions/161688