ディスク領域の割り当てと使用領域を報告するクエリ


29

1つのアプリケーションで合計6つのデータベースを使用しており、6つの自動拡張データベースすべて(SANストレージ経由)で共有できるのは4TBのみです。

SQL Server Management Studioの[タスク]> [圧縮]> [データベース]オプションで[現在割り当てられているスペース]および[使用可能な空きスペース]属性を示す単一のデータベースのクエリ(レポート)を作成します。

次に、これらの数値をTBに変換し、各データベースを合計して、残されたスペースの大まかな見積もりを取得します。T-SQLクエリを介してこれらのフィールドにアクセスできますか?その場合、クエリはどのようになりますか?

データベースの縮小ダイアログ

回答:


40

Management Studioがこれらの番号を設定するために使用するクエリは次のとおりです。

SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df 
   WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df 
   WHERE df.type in (1, 3)) AS [LogSize]
FROM
sys.partitions p join sys.allocation_units a 
  on p.partition_id = a.container_id 
left join sys.internal_tables it 
  on p.object_id = it.object_id

同じ数値を取得するには、Management Studioと同じようにここで計算を実行する必要があります。また、左への結合sys.internal_tablesはせいぜい余分なようです。したがって、理想的な出力に一致するようにクエリを調整します。

SELECT
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
   FROM sys.database_files AS df 
   WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
CONVERT(DECIMAL(18,2), SUM(a.total_pages)*8/1024.0) AS [SpaceUsed],
(SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
   FROM sys.database_files AS df 
   WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p join sys.allocation_units a 
  on p.partition_id = a.container_id;

この更新では、その間データベースが変更されないと仮定すると、次のようになります。

753475.94    744030.07    2900.00

簡単な計算を行い、必要な3つの数値のみを分離します。

;WITH t(s) AS
(
  SELECT CONVERT(DECIMAL(18,2), SUM(size)*8/1024.0)
   FROM sys.database_files
   WHERE [type] % 2 = 0
), 
d(s) AS
(
  SELECT CONVERT(DECIMAL(18,2), SUM(total_pages)*8/1024.0)
   FROM sys.partitions AS p
   INNER JOIN sys.allocation_units AS a 
   ON p.[partition_id] = a.container_id
)
SELECT 
  Allocated_Space = t.s, 
  Available_Space = t.s - d.s,
  [Available_%] = CONVERT(DECIMAL(5,2), (t.s - d.s)*100.0/t.s)
FROM t CROSS APPLY d;

24

アーロンのクエリは優れていますが、代わりに、グレンベリーのDMVクエリからこのクエリを使用します
(TBの計算を変更する必要があります)。

-- Individual File Sizes and space available for current database
-- (Query 36) (File Sizes and Space)
SELECT f.name AS [File Name] , f.physical_name AS [Physical Name], 
CAST((f.size/128.0) AS DECIMAL(15,2)) AS [Total Size in MB],
CAST(f.size/128.0 - CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS int)/128.0 AS DECIMAL(15,2)) 
AS [Available Space In MB], [file_id], fg.name AS [Filegroup Name]
FROM sys.database_files AS f WITH (NOLOCK) 
LEFT OUTER JOIN sys.data_spaces AS fg WITH (NOLOCK) 
ON f.data_space_id = fg.data_space_id OPTION (RECOMPILE);

9

役に立つSQLをいくつか紹介します。


Create Table #dbInfo (dId smallint, dbName sysname, gId smallint NULL, segName varchar(256) NULL, 
       filName varchar(520) NULL, sizeMg decimal(10,2) null, 
       usedMg decimal(10,2) null, freeMg decimal(10,2) null, 
       pcntUsed decimal(10,2) null, pcntFree decimal(10,2) null)
Declare @sSql varchar(1000)
Set @sSql = 'Use [?];
Insert #dbInfo (dId, dbName, gid, segName, filName, sizeMg, usedMg)
Select db_id(), db_name(), groupid, rtrim(name), filename, Cast(size/128.0 As Decimal(10,2)), 
Cast(Fileproperty(name, ''SpaceUsed'')/128.0 As Decimal(10,2))
From dbo.sysfiles Order By groupId Desc;'
Exec sp_MSforeachdb @sSql
Update #dbInfo Set
freeMg = sizeMg - usedMg,
pcntUsed = (usedMg/sizeMg)*100,
pcntFree = ((sizeMg-usedMg)/sizeMg)*100

select * from #dbInfo compute sum(sizeMG),  sum(FreeMg) 
drop table #dbInfo

これは古いSQLですが、まだ機能しています。最近では、Aaronの答えのようにsys.database_filesを使用するように書き直そうとしています。


7

同様の質問(True Physical Database File Sizesのクエリ)に取り組んだ後、さまざまなファイルサイズを表示するクエリ(たとえば、ログとデータベース、およびディスク上のファイルのサイズ)は、ほとんどのユーザーにとってより役立つと思います。

これには、システムファイルサイズとディスク上で使用するスペースの量、SQLファイルサイズ、使用されるSQLスペース、および拡張機能によりSQLの空きスペースが含まれます。評価されるファイルの完全なパスが含まれます。デフォルト(4096バイト)とは異なる割り当てサイズを使用してディスクがフォーマットされている場合、ユーザーは 'Size_On_Disk_Bytes'の計算を変更する必要があります。

SELECT fg.data_space_id AS FGID,
   (f.file_id) AS File_Id,
   -- As provided by OP, size on disk in bytes.
   REPLACE(CONVERT(VARCHAR,CONVERT(MONEY, CAST(f.size AS FLOAT) * 8.00 * 1024), 1), '.00','') AS Size_On_Disk_Bytes,
   ROUND((CAST(f.size AS FLOAT) * 8.00/1024)/1024,3) AS Actual_File_Size,
   ROUND(CAST((f.size) AS FLOAT)/128,2) AS Reserved_MB,
   ROUND(CAST((FILEPROPERTY(f.name,'SpaceUsed')) AS FLOAT)/128,2) AS Used_MB,
   ROUND((CAST((f.size) AS FLOAT)/128)-(CAST((FILEPROPERTY(f.name,'SpaceUsed'))AS FLOAT)/128),2) AS Free_MB,
   f.name,
   f.physical_name
FROM sys.database_files f 
    LEFT JOIN sys.filegroups fg
    ON f.data_space_id = fg.data_space_id

さらに、このクエリは、ファイルをホストするボリュームドライブの領域に関する情報を返します。ユーザーはsys.master_filesにアクセスする必要があります。

SELECT DISTINCT dovs.logical_volume_name AS LogicalName,
dovs.volume_mount_point AS Drive,
CONVERT(INT,dovs.available_bytes/1048576.0) AS FreeSpaceInMB
FROM sys.master_files mf
CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.FILE_ID) dovs
ORDER BY FreeSpaceInMB ASC

実際に単位(MB)を含めることに賛成です。含めることが非常に重要なようです。
ddunn801

0

私がまとめたもの。これを実行するには、SQL ServerでPOWERSHELLが必要です。バージョンがわからない。これにより、ドライブのサイズが取得され、ファイルサイズと空き領域、および空きドライブ領域が報告されます。

100%オリジナルではなく、その一部をインターネット上の他の場所で見つけて、全体をまとめました。あなたが括弧で遊ぶ必要があるかもしれないので、適切なマージンに収まるようにするのはPITAでした

--drop table ##DB_FILE_INFO
 --alter procedure super_drive_info3 

 --as

  if exists ( select * from tempdb.dbo.sysobjects o
    where o.xtype in ('U') and o.name in ('##DB_FILE_INFO' ))
drop table ##DB_FILE_INFO

if exists ( select * from tempdb.dbo.sysobjects o
    where o.xtype in ('U') and o.name in ('##output'))
drop table ##output

 create table ##DB_FILE_INFO (
[server_Name] varchar(255) not null,
[database_name] varchar(255) not null,
[File_ID]           int     not null,
[File_Type]     int     not null ,
[Drive]     varchar(255)    not null ,
[Logical_Name]      varchar(255)    not null ,
[Physical_Name]     varchar(255)    not null ,
[FILE_SIZE_MB]      int     not null ,
[SPace_USED_MB] int     not null ,
[Free_space]    int     not null ,
[Max_SIZE]      int     not null ,
[Percent_Log_growth_enabled]    int     not null ,
[growth_rate]   int     not null ,
[current_date]      datetime        not null
)
--go
declare @sql    nvarchar(4000)
set @sql =
'use ['+'?'+']
 --if db_name() <> N''?'' goto Error_Exit
 insert into ##DB_FILE_INFO
(
    [server_Name],
    [database_name],
    [File_ID],
[File_Type],
[Drive],
[Logical_Name],
[Physical_Name],
[FILE_SIZE_MB],
[SPace_USED_MB],
[Free_space],
[Max_SIZE],
[Percent_Log_growth_enabled],
[growth_rate],
[current_date]
)
SELECT 
@@servername as [Server_Name],
db_name() as database_name,
[file_id] AS [File_ID],
[type] AS [File_Type],
substring([physical_name],1,1) AS [Drive],
[name] AS [Logical_Name],
[physical_name] AS [Physical_Name],
CAST([size] as DECIMAL(38,0))/128. AS [File Size MB], 
CAST(FILEPROPERTY([name],''SpaceUsed'') AS DECIMAL(38,0))/128. AS 
[Space_Used_MB], 
(CAST([size] AS DECIMAL(38,0))/128) - 
(CAST(FILEPROPERTY([name],''SpaceUsed'') AS DECIMAL(38,0))/128.) AS [Free 
 Space],
[max_size] AS [Max_Size],
[is_percent_growth] AS [Percent_Growth_Enabled],
[growth] AS [Growth Rate],
getdate() AS [Current_Date]
FROM sys.database_files'
 exec sp_msforeachdb @sql
 declare @svrName varchar(255)
declare @sql2 varchar(400)
--by default it will take the current server name, we can the set the server 
name as well
set @svrName = @@SERVERNAME
set @sql2 = 'powershell.exe -c "Get-WmiObject -ComputerName ' + 
QUOTENAME(@svrName,'''') + ' -Class Win32_Volume -Filter ''DriveType = 3'' | 
select name,capacity,freespace | 

foreach{$_.name+''|
 ''+$_.capacity/1048576+''%''+$_.freespace/1048576+''*''}"'
 --creating a temporary table
 CREATE TABLE ##output
 (line varchar(255))
 --inserting  in to temporary table
 insert ##output
 EXEC xp_cmdshell @sql2;

 with Output2 
 --(drivename, capacity(gb),freespace(gb), always_on_status)
 as
 (
 select @@servername as server_name, 
rtrim(ltrim(SUBSTRING(line,1,CHARINDEX(':',line) -1))) as drivename
 ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('|',line)+1,
 (CHARINDEX('%',line) -1)-CHARINDEX('|',line)) )) as float)/1024,2) as 
 'capacityGB'
 ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('%',line)+1,
 (CHARINDEX('*',line) -1)-CHARINDEX('%',line)) )) as float) /1024 ,2)as 
 'freespaceGB'
 ,CASE WHEN (SERVERPROPERTY ('IsHadrEnabled')=1) THEN 'YES' WHEN 
 (SERVERPROPERTY ('IsHadrEnabled')=0) THEN 'NO'ELSE 'NOT AVAILABLE' END AS 
 ALWAYS_ON_STATUS
  --into #output2
 from ##output
   where line like '[A-Z][:]%'
   --order by drivename
  ),
  DB_FILE_INFO2 as
 (
 select server_Name,
    database_name,
    File_ID,
File_Type,
Drive,
Logical_Name,
Physical_Name,
FILE_SIZE_MB,
SPace_USED_MB,
Free_space,
Max_SIZE,
Percent_Log_growth_enabled,
growth_rate
--current_date 
from ##DB_FILE_INFO 
--inner join #output b on a.drive = b.drivename and a.server_Name = 
b.server_name
)
select  
getdate() as Today_Date,
a.server_Name,
a.database_name,
a.Drive,
a.Logical_Name,
a.Physical_Name,
a.FILE_SIZE_MB,
a.Space_Used_MB,
--sum(a.SPace_USED_MB) as hg,
a.Free_space as Free_Space_in_File,
 --Percentage_file_free = (a.Space_Used_MB/a.FILE_SIZE_MB),
b.capacitygb as Total_Drive_capacity,
b.freespacegb as Total_Free_Space,
c.total_log_size_mb,
c.active_log_size_mb
--,Percentage_free_space = ((cast(Free_space as decimal))/(cast(FILE_SIZE_MB 
as decimal)) * 100)

from DB_FILE_INFO2 a
inner join output2 b on a.server_Name = b.server_name and a.Drive = 
 b.drivename
cross apply sys.dm_db_log_stats (db_id(a.database_name)) c
order by a.Drive, a.database_name

--drop table ##DB_FILE_INFO
--drop table #output

0

以下のスクリプトを使用して、次の情報を取得できます。1. DBサイズ情報2. FileSpaceInfo 3. AutoGrowth 4.復旧モデル5. Log_reuse_backup情報

CREATE TABLE #tempFileInformation
(
DBNAME          NVARCHAR(256),
[FILENAME]      NVARCHAR(256),
[TYPE]          NVARCHAR(120),
FILEGROUPNAME   NVARCHAR(120),
FILE_LOCATION   NVARCHAR(500),
FILESIZE_MB     DECIMAL(10,2),
USEDSPACE_MB    DECIMAL(10,2),
FREESPACE_MB    DECIMAL(10,2),
AUTOGROW_STATUS NVARCHAR(100)
)
GO

DECLARE @SQL VARCHAR(2000)

SELECT @SQL = '
 USE [?]
            INSERT INTO #tempFileInformation
            SELECT  
                DBNAME          =DB_NAME(),     
                [FILENAME]      =A.NAME,
                [TYPE]          = A.TYPE_DESC,
                FILEGROUPNAME   = 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 - ((A.SIZE - 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)),
                AUTOGROW_STATUS = ''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]'' 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
    ;
    '

    --print @sql

    EXEC sp_MSforeachdb @SQL
    go

    SELECT dbSize.*,fg.*,d.log_reuse_wait_desc,d.recovery_model_desc
    FROM #tempFileInformation fg
    LEFT JOIN sys.databases d on fg.DBNAME = d.name
    CROSS APPLY
    (
        select dbname,
                sum(FILESIZE_MB) as [totalDBSize_MB],
                sum(FREESPACE_MB) as [DB_Free_Space_Size_MB],
                sum(USEDSPACE_MB) as [DB_Used_Space_Size_MB]
            from #tempFileInformation
            where  dbname = fg.dbname
            group by dbname
    )dbSize


go
DROP TABLE #tempFileInformation
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.