SQL Server 2008 : 모든 데이터베이스 크기를 쿼리하는 방법은 무엇입니까?


124

MS SQL 2008 R2, 500 데이터베이스가 있습니다. 모든 데이터베이스 크기를 쿼리하는 가장 효율적이고 가장 쉽고 '현대적인'방법은 무엇입니까?

출력에는 다음 열이 있어야합니다.

  • 데이터베이스 이름
  • DataFilesSize
  • LogFilesSize

답변:


223
with fs
as
(
    select database_id, type, size * 8.0 / 1024 size
    from sys.master_files
)
select 
    name,
    (select sum(size) from fs where type = 0 and fs.database_id = db.database_id) DataFileSizeMB,
    (select sum(size) from fs where type = 1 and fs.database_id = db.database_id) LogFileSizeMB
from sys.databases db

15
@Derek Smith-크기 열이 페이지에 있습니다. 한 페이지의 크기는 8kB이므로 공식 SizeInMb = PagesCount * 8/1024입니다. 저는 항상 1MB = 1024kB라고 믿었습니다. 나는 마이크로 소프트조차도 이것을 바꿀 충분한 힘을 가지고 있다고 생각하지 않는다. :).
Alex Aza 2013 년

1
이 대답은 어떤 이유로 시스템에서 tempdb에 대한 잘못된 값을보고합니다. 이 관련 질문을 참조하십시오 .
crokusek

40

효율성이 무엇을 의미하는지 정확히 모르지만 이것은 간단하며 저에게 효과적입니다.

SELECT
    DB_NAME(db.database_id) DatabaseName,
    (CAST(mfrows.RowSize AS FLOAT)*8)/1024 RowSizeMB,
    (CAST(mflog.LogSize AS FLOAT)*8)/1024 LogSizeMB,
    (CAST(mfstream.StreamSize AS FLOAT)*8)/1024 StreamSizeMB,
    (CAST(mftext.TextIndexSize AS FLOAT)*8)/1024 TextIndexSizeMB
FROM sys.databases db
    LEFT JOIN (SELECT database_id, SUM(size) RowSize FROM sys.master_files WHERE type = 0 GROUP BY database_id, type) mfrows ON mfrows.database_id = db.database_id
    LEFT JOIN (SELECT database_id, SUM(size) LogSize FROM sys.master_files WHERE type = 1 GROUP BY database_id, type) mflog ON mflog.database_id = db.database_id
    LEFT JOIN (SELECT database_id, SUM(size) StreamSize FROM sys.master_files WHERE type = 2 GROUP BY database_id, type) mfstream ON mfstream.database_id = db.database_id
    LEFT JOIN (SELECT database_id, SUM(size) TextIndexSize FROM sys.master_files WHERE type = 4 GROUP BY database_id, type) mftext ON mftext.database_id = db.database_id

결과는 다음과 같습니다.

DatabaseName  RowSizeMB LogSizeMB StreamSizeMB TextIndexSizeMB
------------- --------- --------- ------------ ---------------
master        4         1.25      NULL         NULL
model         2.25      0.75      NULL         NULL
msdb          14.75     8.1875    NULL         NULL
tempdb        8         0.5       NULL         NULL

참고 : 이 기사 에서 영감을 얻었습니다.


7
이것을 사용하는 모든 열에서 NULL 값을 얻습니까? 왜 그런지 아세요?
BSanders

2
sys.master_files가 비어 있으면 권한 일 수 있습니다. 최소 권한은 CREATE DATABASE, ALTER ANY DATABASE 또는 VIEW ANY DEFINITION (참조 : BOL sys.master_files)
Stagg 2014 년

19

다음은 모든 데이터베이스 및 로그 파일 이름, 크기 및 데이터베이스 상태 (예 : ONLINE)를 읽기 쉬운 출력으로 제공하는 간단하고 빠르고 신뢰할 수있는 쿼리입니다.

SELECT
    D.name,
    F.Name AS FileType,
    F.physical_name AS PhysicalFile,
    F.state_desc AS OnlineStatus,
    CAST(F.size AS bigint) * 8*1024 AS SizeInBytes,
    CAST((F.size*8.0)/1024/1024 AS decimal(18,3)) AS SizeInGB
FROM 
    sys.master_files F
    INNER JOIN sys.databases D ON D.database_id = F.database_id
ORDER BY SizeInBytes desc

7

총 데이터베이스 크기가 Desc로 정렬 됨

SELECT     
DB_NAME(db.database_id) DatabaseName,     
(CAST(mfrows.RowSize AS FLOAT)*8)/1024 RowSizeMB,     
(CAST(mflog.LogSize AS FLOAT)*8)/1024 LogSizeMB, 
(CAST(mfrows.RowSize AS FLOAT)*8)/1024/1024+(CAST(mflog.LogSize AS FLOAT)*8)/1024/1024 DBSizeG,
(CAST(mfstream.StreamSize AS FLOAT)*8)/1024 StreamSizeMB,     
(CAST(mftext.TextIndexSize AS FLOAT)*8)/1024 TextIndexSizeMB 
FROM sys.databases db     
LEFT JOIN (SELECT database_id, 
                  SUM(size) RowSize 
            FROM sys.master_files 
            WHERE type = 0 
            GROUP BY database_id, type) mfrows 
    ON mfrows.database_id = db.database_id     
LEFT JOIN (SELECT database_id, 
                  SUM(size) LogSize 
            FROM sys.master_files 
            WHERE type = 1 
            GROUP BY database_id, type) mflog 
    ON mflog.database_id = db.database_id     
LEFT JOIN (SELECT database_id, 
                  SUM(size) StreamSize 
                  FROM sys.master_files 
                  WHERE type = 2 
                  GROUP BY database_id, type) mfstream 
    ON mfstream.database_id = db.database_id     
LEFT JOIN (SELECT database_id, 
                  SUM(size) TextIndexSize 
                  FROM sys.master_files 
                  WHERE type = 4 
                  GROUP BY database_id, type) mftext 
    ON mftext.database_id = db.database_id 
       ORDER BY 4 DESC

7

모두 지나치게 복잡해 보입니다! 아니면 내가 뭔가를 놓치고 있습니까?

확실히 필요한 것은 다음과 같습니다.

select d.name, case when m.type = 0 then 'Data' else 'Log' end,  m.size * 8 / 1024
from sys.master_files m JOIN sys.databases d ON d.database_id = m.database_id

또는 로그를 원하지 않는 경우 :

select d.name, m.size * 8 / 1024
from sys.master_files m JOIN sys.databases d ON d.database_id = m.database_id and m.type =0

5

자세한 내용을 찾거나 아래 링크에서 스크립트를 다운로드하십시오. https://gallery.technet.microsoft.com/SIZE-OF-ALL-DATABASES-IN-0337f6d5#content

 DECLARE @spacetable table
 (
 database_name varchar(50) ,
 total_size_data int,
 space_util_data int,
 space_data_left int,
 percent_fill_data float,
 total_size_data_log int,
 space_util_log int,
 space_log_left int,
 percent_fill_log char(50),
 [total db size] int,
 [total size used] int,
 [total size left] int
 )
 insert into  @spacetable
 EXECUTE master.sys.sp_MSforeachdb 'USE [?];
 select x.[DATABASE NAME],x.[total size data],x.[space util],x.[total size data]-x.[space util] [space left data],
 x.[percent fill],y.[total size log],y.[space util],
 y.[total size log]-y.[space util] [space left log],y.[percent fill],
 y.[total size log]+x.[total size data] ''total db size''
 ,x.[space util]+y.[space util] ''total size used'',
 (y.[total size log]+x.[total size data])-(y.[space util]+x.[space util]) ''total size left''
  from (select DB_NAME() ''DATABASE NAME'',
 sum(size*8/1024) ''total size data'',sum(FILEPROPERTY(name,''SpaceUsed'')*8/1024) ''space util''
 ,case when sum(size*8/1024)=0 then ''less than 1% used'' else
 substring(cast((sum(FILEPROPERTY(name,''SpaceUsed''))*1.0*100/sum(size)) as CHAR(50)),1,6) end ''percent fill''
 from sys.master_files where database_id=DB_ID(DB_NAME())  and  type=0
 group by type_desc  ) as x ,
 (select 
 sum(size*8/1024) ''total size log'',sum(FILEPROPERTY(name,''SpaceUsed'')*8/1024) ''space util''
 ,case when sum(size*8/1024)=0 then ''less than 1% used'' else
 substring(cast((sum(FILEPROPERTY(name,''SpaceUsed''))*1.0*100/sum(size)) as CHAR(50)),1,6) end ''percent fill''
 from sys.master_files where database_id=DB_ID(DB_NAME())  and  type=1
 group by type_desc  )y'
 select * from @spacetable
 order by database_name

4
SELECT
    DB.name,
    SUM(CASE WHEN type = 0 THEN MF.size * 8 / 1024 ELSE 0 END) AS DataFileSizeMB,
    SUM(CASE WHEN type = 1 THEN MF.size * 8 / 1024 ELSE 0 END) AS LogFileSizeMB
FROM
    sys.master_files MF
    JOIN sys.databases DB ON DB.database_id = MF.database_id
GROUP BY DB.name
ORDER BY DataFileSizeMB DESC

1
GROUP BY DB.name, DB.database_id ORDER BY DB.database_id 테이블 순서를 유지합니다.
samis

1

나는 최근에 이와 같은 것을 찾고있는이 페이지를 보았습니다. 누군가가 이것을 발견하고 핵심 사용자 데이터베이스에만 관심이있는 경우 Master, msdb를 제외한 다음과 같은 것을 사용할 수 있습니다.

SELECT
DB_NAME(db.database_id) DatabaseName,
(CAST(mfrows.RowSize AS FLOAT)*8)/1024 RowSizeMB,
(CAST(mflog.LogSize AS FLOAT)*8)/1024 LogSizeMB
FROM sys.databases db
LEFT JOIN (SELECT database_id, SUM(size) RowSize FROM sys.master_files WHERE type = 0 GROUP BY database_id, type) mfrows ON mfrows.database_id = db.database_id
LEFT JOIN (SELECT database_id, SUM(size) LogSize FROM sys.master_files WHERE type = 1 GROUP BY database_id, type) mflog ON mflog.database_id = db.database_id
where DB_NAME(db.database_id) not like 'master'
and DB_NAME(db.database_id) not like 'msdb'
and DB_NAME(db.database_id) not like 'model'
and DB_NAME(db.database_id) not like 'tempdb'
and DB_NAME(db.database_id) not like 'Northwind'
and DB_NAME(db.database_id) not like 'ReportServer'
order by DB_NAME(db.database_id)

1
IF OBJECT_ID('tempdb.dbo.#space') IS NOT NULL
    DROP TABLE #space

CREATE TABLE #space (
      database_id INT PRIMARY KEY
    , data_used_size DECIMAL(18,2)
    , log_used_size DECIMAL(18,2)
)

DECLARE @SQL NVARCHAR(MAX)

SELECT @SQL = STUFF((
    SELECT '
    USE [' + d.name + ']
    INSERT INTO #space (database_id, data_used_size, log_used_size)
    SELECT
          DB_ID()
        , SUM(CASE WHEN [type] = 0 THEN space_used END)
        , SUM(CASE WHEN [type] = 1 THEN space_used END)
    FROM (
        SELECT s.[type], space_used = SUM(FILEPROPERTY(s.name, ''SpaceUsed'') * 8. / 1024)
        FROM sys.database_files s
        GROUP BY s.[type]
    ) t;'
    FROM sys.databases d
    WHERE d.[state] = 0
    FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 2, '')

EXEC sys.sp_executesql @SQL

SELECT
      d.database_id
    , d.name
    , d.state_desc
    , d.recovery_model_desc
    , t.total_size
    , t.data_size
    , s.data_used_size
    , t.log_size
    , s.log_used_size
FROM (
    SELECT
          database_id
        , log_size = CAST(SUM(CASE WHEN [type] = 1 THEN size END) * 8. / 1024 AS DECIMAL(18,2))
        , data_size = CAST(SUM(CASE WHEN [type] = 0 THEN size END) * 8. / 1024 AS DECIMAL(18,2))
        , total_size = CAST(SUM(size) * 8. / 1024 AS DECIMAL(18,2))
    FROM sys.master_files
    GROUP BY database_id
) t
JOIN sys.databases d ON d.database_id = t.database_id
LEFT JOIN #space s ON d.database_id = s.database_id
ORDER BY t.total_size DESC

1

답을 훔쳐서 점수 나 다른 것에 적용하는 것이 아니라 여기에 또 다른 분해가 있습니다.

select d.name, 
    sum(m0.size*8.0/1024) data_file_size_mb, 
    sum(m1.size*8.0/1024) log_file_size_mb 
from sys.databases d
inner join sys.master_files m0 on m0.database_id = d.database_id
inner join sys.master_files m1 on m1.database_id = d.database_id
where m0.type = 0 and m1.type = 1
group by d.name, d.database_id
order by d.database_id

1
Mihai Bejenariu의 대답은 내가 여기서 시도한 것에 더 가깝습니다.
samis

0

더 좋고 아주 간단한 것

SELECT [Database Name] = DB_NAME(database_id),
     [Type] = CASE WHEN Type_Desc = 'ROWS' THEN 'Data File(s)'
               WHEN Type_Desc = 'LOG'  THEN 'Log File(s)'
               ELSE Type_Desc END,
     [Size in MB] = CAST( ((SUM(Size)* 8) / 1024.0) AS DECIMAL(18,2) )
FROM   sys.master_files
--Uncomment if you need to query for a particular database
--WHERE      database_id = DB_ID(‘Database Name’) 
GROUP BY  GROUPING SETS
        (
               (DB_NAME(database_id), Type_Desc),
               (DB_NAME(database_id))
        ) ORDER BY      DB_NAME(database_id), Type_Desc DESC

아래와 같이 데이터 파일과 로그 파일의 크기를 별도로 제공합니다.

DatabaseName    Type            Size in MB
-------------------------------------------
FMS             Data File(s)    23.00
FMS             Log File(s)     1.50
PointOfSale     Data File(s)    4.00
PointOfSale     Log File(s)     1.25
Union2          Data File(s)    336.00
Union2          Log File(s)     1191.13
SurveyProject   Data File(s)    4.00
SurveyProject   Log File(s)     1.00

이는 두 그룹화 세트의 출력이 아닙니다.
Gert Arnold

0

다음 코드는 나를 위해 아주 잘 작동했습니다.

    SELECT
        D.name As DbName,
        F.Name AS FullDbName,
        CASE WHEN F.type_desc='ROWS' THEN 'mdf' ELSE 'ldf' END AS FileType,
        F.physical_name AS PhysicalFile,
        CONVERT(DATE,D.create_date) AS CreationDate,
        F.state_desc AS OnlineStatus,
        CAST((F.size*8)/1024 AS VARCHAR(26)) + ' MB' AS FileSize_MB,
        CAST(F.size*8 AS VARCHAR(32)) + ' Bytes' AS FileSize_Bytes,
        CAST(CAST(ROUND((F.size*8)/(1024.0*1024.0),0) AS INT) AS VARCHAR(32)) + ' GB' AS FileSize_GB

    FROM 
        sys.master_files F
        INNER JOIN sys.databases D ON D.database_id = F.database_id

    ORDER BY
         D.name 

0

단순화 및 개선 된 버전 :

SELECT
    D.name,
    CAST(SUM(F.size) AS bigint) * 8*1024 AS SizeInBytes,
    CAST(SUM(F.size*8.0)/1024/1024 AS decimal(18,3)) AS SizeInGB
FROM 
    sys.master_files F
    INNER JOIN sys.databases D ON D.database_id = F.database_id
GROUP BY D.name
ORDER BY SizeInBytes desc

-1

때로는 SECURITY 문제로 인해 모든 db를 요청하지 못하며 db 접두사를 사용하여 하나씩 쿼리해야합니다.이 경우이 동적 쿼리를 만든 경우

go
declare @Results table ([Name] nvarchar(max), [DataFileSizeMB] int, [LogFileSizeMB] int);

declare @QaQuery nvarchar(max)
declare @name nvarchar(max)

declare MY_CURSOR cursor 
  local static read_only forward_only
for 
select name from master.dbo.sysdatabases where name not in ('master', 'tempdb', 'model', 'msdb', 'rdsadmin');

open MY_CURSOR
fetch next from MY_CURSOR into @name
while @@FETCH_STATUS = 0
begin 
    if(len(@name)>0)
    begin
        print @name + ' Column Exist'
        set @QaQuery = N'select 
                            '''+@name+''' as Name
                            ,sum(case when type = 0 then size else 0 end) as DataFileSizeMB
                            ,sum(case when type = 1 then size else 0 end) as LogFileSizeMB
                        from ['+@name+'].sys.database_files
                        group by replace(name, ''_log'', '''')';

        insert @Results exec sp_executesql @QaQuery;
    end
  fetch next from MY_CURSOR into @name
end
close MY_CURSOR
deallocate MY_CURSOR

select * from @Results order by DataFileSizeMB desc
go
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.