我们在删除数据的while循环中使用“sp_spaceused” 我们这样做是为了保持在10GB SQL Express Edition限制之下。
每晚运行的删除例程
PROCEDURE [dbo].[DeletePeriod4Data]
@LIMIT_InMB AS FLOAT
AS
BEGIN
SET NOCOUNT ON
DECLARE @MinBegin AS DATETIME
DECLARE @SizePeriod4_InMB AS FLOAT
EXEC [dbo].[GetDatabaseStatsPeriod4MB]
@Size_InMB = @SizePeriod4_InMB OUTPUT
WHILE @SizePeriod4_InMB > @LIMIT_InMB
BEGIN
SELECT @MinBegin = MIN(MONTH.ProdData.[Begin])
FROM MONTH.ProdData
PRINT 'deleting from period 4, month and year of: '
PRINT @MinBegin
DELETE
FROM Month.ProdData
WHERE
Year = DATEPART(YEAR, @MinBegin)
AND
Month = DATEPART(MONTH, @MinBegin)
EXEC [GetDatabaseStatsPeriod4MB]
@Size_InMB = @SizePeriod4_InMB OUTPUT
END
END
这是返回outofdate数字的罪魁祸首存储过程。
PROCEDURE [dbo].[GetDatabaseStatsPeriod4MB]
@Size_InMB float OUTPUT
AS
BEGIN
CREATE TABLE #t (name SYSNAME, rows CHAR(11), reserved VARCHAR(18),
data VARCHAR(18), index_size VARCHAR(18), unused VARCHAR(18))
DBCC UPDATEUSAGE(0); -- <-- helps?
EXEC sp_msforeachtable @command1=
'INSERT INTO #t EXEC sp_spaceused ''?'', @updateUsage=''TRUE''',
@whereand=' and schema_name(schema_id) = ''Month'' '
SELECT @Size_InMB =
SUM(CONVERT(INT, SUBSTRING(data, 1, LEN(data)-3)))/1024.0
FROM #t
DROP TABLE #t
PRINT 'PERIODE 4 Size (Month)'
PRINT @Size_InMB
END
我们尝试的是
重现问题的通用代码
CREATE TABLE #t (name SYSNAME, rows CHAR(11), reserved VARCHAR(18),
data VARCHAR(18), index_size VARCHAR(18), unused VARCHAR(18))
EXEC sp_msforeachtable @command1=
'INSERT INTO #t EXEC sp_spaceused ''?'', @updateUsage=''TRUE'''
SELECT SUM(CONVERT(INT, SUBSTRING(data, 1, LEN(data)-3)))/1024.0
FROM #t
DROP TABLE #t
-- Delete something in your DB (Northwind)
-- Run the above again
答案 0 :(得分:2)
你需要花时间让Ghost Cleanup处理幻影记录,因为DELETE实际上并没有删除任何东西,它只是将记录标记为页面上的插槽中的幻像,然后它就是Ghost Cleanup任务的工作以后清理那些。您可以在Paul的博客文章中了解这一点:
Inside the Storage Engine - Ghost Cleanup in Depth
Truning off the Ghost Cleanup Task for a Performance Gain
您还可以在我的博客文章中显示SQL Server 2008+中的扩展事件跟踪Ghost清理活动:
您需要在删除和检查用于允许Ghost清理运行的空间之间或在删除和检查所用空间之间等待,通过强制进行索引扫描来强制进行Ghost清理,正如Paul在他的博客文章中所解释的那样。 / p>