1

データを削除するwhileループで「sp_spaceused」を使用します。
これは、SQLExpressEditionの10GBの制限を超えないようにするためです。

毎晩実行される削除ルーチン

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

そして、これは古い番号を返す原因のストアドプロシージャです。

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. 「DBCCUPDATEUSAGE(0);」への呼び出しを追加しました。
  3. 「DBCCUPDATEUSAGE(0)WITH NO_INFOMSGS、COUNT_ROWS;」にパラメータを追加しました。
  4. 「UpdateUsage」を呼び出す前に遅延を使用する<br>WAITFORDELAY '00:00:05'----5秒の遅延

問題を再現するためのジェネリックコード

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
4

1 に答える 1

2

DELETE は実際には何も削除しないため、Ghost Cleanup がゴースト化されたレコードを処理するための時間を考慮する必要があります。DELETE はレコードをページのスロットでゴースト化されているとマークするだけであり、それらをクリーンアップするのは Ghost Cleanup タスクの仕事です。後でアップします。これについては、ポールのブログ投稿で読むことができます。

ストレージ エンジンの内部 - 詳細なゴースト クリーンアップ

ゴースト クリーンアップ - Redux

パフォーマンス向上のためにゴースト クリーンアップ タスクをオフにする

また、私のブログ投稿に示されているように、SQL Server 2008 以降の拡張イベントを使用してゴースト クリーンアップ アクティビティを追跡することもできます。

トラッキング ゴースト クリーンアップ

削除してから Ghost クリーンアップを実行できるようにするために使用されるスペースを確認するまで、または削除してから使用されているスペースを確認するまで待つ必要があります。

于 2012-08-01T11:49:27.173 に答える