it-swarm.it

Come determinare lo spazio usato / libero all'interno dei file del database SQL?

Normalmente utilizzo il seguente metodo per determinare lo spazio libero/utilizzato all'interno di ciascun file di un database:

Select *, fileproperty(name, 'SpaceUsed') as Used
From dbo.sysfiles

Ciò restituisce lo spazio totale e utilizzato nelle pagine, che quindi moltiplico per 8 per ottenere KB (o divido per 128,0 per ottenere MB).

Ho trovato un altro script che utilizza invece DBCC showfilestats E dbcc sqlperf(logspace) per restituire TotalExtents e UsedExtents, che possono quindi essere moltiplicati per 64 per ottenere KB (o divisi per 16.0 per ottenere MB).

Ignorando le colonne aggiuntive, questi due forniranno sempre valori identici per lo spazio libero/totale? Che dire di sp_spaceused?

La loro precisione dipende da un recente AGGIORNAMENTO DBCC?

Esiste un altro metodo migliore per determinare lo spazio usato/libero? (Ho bisogno che questo script funzioni su server SQL 2000, 2005 e 2008)

Parzialmente correlato: puoi avere un'estensione parzialmente allocata? (ad esempio, solo 3 delle 8 pagine di una determinata estensione sono allocate)

14
BradC

Questo funziona per me e sembra essere coerente su CTP3 da SQL 2000 a SQL Server 2012:

SELECT RTRIM(name) AS [Segment Name], groupid AS [Group Id], filename AS [File Name],
   CAST(size/128.0 AS DECIMAL(10,2)) AS [Allocated Size in MB],
   CAST(FILEPROPERTY(name, 'SpaceUsed')/128.0 AS DECIMAL(10,2)) AS [Space Used in MB],
   CAST([maxsize]/128.0 AS DECIMAL(10,2)) AS [Max in MB],
   CAST(size/128.0-(FILEPROPERTY(name, 'SpaceUsed')/128.0) AS DECIMAL(10,2)) AS [Available Space in MB],
   CAST((CAST(FILEPROPERTY(name, 'SpaceUsed')/128.0 AS DECIMAL(10,2))/CAST(size/128.0 AS DECIMAL(10,2)))*100 AS DECIMAL(10,2)) AS [Percent Used]
FROM sysfiles
ORDER BY groupid DESC

Un'alternativa (non compatibile con SQL Server 200) che fornisce ulteriori informazioni, suggerita da Tri Effendi SS :

USE [database name]
GO
SELECT 
    [TYPE] = A.TYPE_DESC
    ,[FILE_Name] = A.name
    ,[FILEGROUP_NAME] = fg.name
    ,[File_Location] = A.PHYSICAL_NAME
    ,[FILESIZE_MB] = CONVERT(DECIMAL(10,2),A.SIZE/128.0)
    ,[USEDSPACE_MB] = CONVERT(DECIMAL(10,2),A.SIZE/128.0 - ((SIZE/128.0) - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT)/128.0))
    ,[FREESPACE_MB] = CONVERT(DECIMAL(10,2),A.SIZE/128.0 - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT)/128.0)
    ,[FREESPACE_%] = CONVERT(DECIMAL(10,2),((A.SIZE/128.0 - CAST(FILEPROPERTY(A.NAME, 'SPACEUSED') AS INT)/128.0)/(A.SIZE/128.0))*100)
    ,[AutoGrow] = 'By ' + CASE is_percent_growth WHEN 0 THEN CAST(growth/128 AS VARCHAR(10)) + ' MB -' 
        WHEN 1 THEN CAST(growth AS VARCHAR(10)) + '% -' ELSE '' END 
        + CASE max_size WHEN 0 THEN 'DISABLED' WHEN -1 THEN ' Unrestricted' 
            ELSE ' Restricted to ' + CAST(max_size/(128*1024) AS VARCHAR(10)) + ' GB' END 
        + CASE is_percent_growth WHEN 1 THEN ' [autogrowth by percent, BAD setting!]' ELSE '' END
FROM sys.database_files A LEFT JOIN sys.filegroups fg ON A.data_space_id = fg.data_space_id 
order by A.TYPE desc, A.NAME; 
39
Bruce