“sp_spaceused”不返回uptodate数字

时间:2012-08-01 08:06:39

标签: sql-server-express

我们在删除数据的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

我们尝试的是

  1. 将参数“@ updateUsage = TRUE”添加到sp_spaceused
  2. 添加了对“DBCC UPDATEUSAGE(0);”
  3. 的调用
  4. 在“DBCC UPDATEUSAGE(0)NO_INFOMSGS,COUNT_ROWS;”
  5. 中添加了参数
  6. 在我调用“UpdateUsage”之前使用延迟
    WAITFOR DELAY '00:00:05'---- 5秒延迟

  7. 重现问题的通用代码

    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
    

1 个答案:

答案 0 :(得分:2)

你需要花时间让Ghost Cleanup处理幻影记录,因为DELETE实际上并没有删除任何东西,它只是将记录标记为页面上的插槽中的幻像,然后它就是Ghost Cleanup任务的工作以后清理那些。您可以在Paul的博客文章中了解这一点:

Inside the Storage Engine - Ghost Cleanup in Depth

Ghost Cleanup - Redux

Truning off the Ghost Cleanup Task for a Performance Gain

您还可以在我的博客文章中显示SQL Server 2008+中的扩展事件跟踪Ghost清理活动:

Tracking Ghost Cleanup

您需要在删除和检查用于允许Ghost清理运行的空间之间或在删除和检查所用空间之间等待,通过强制进行索引扫描来强制进行Ghost清理,正如Paul在他的博客文章中所解释的那样。 / p>