137 votes

SQL Server 2008 : Comment interroger toutes les tailles de bases de données ?

J'ai MS SQL 2008 R2, 500 bases de données. Quelle est la méthode la plus efficace, la plus simple et la plus "moderne" pour interroger toutes les bases de données, quelle que soit leur taille ?

La sortie devrait avoir des colonnes :

  • Nom de la base de données
  • DataFilesSize
  • LogFilesSize

243voto

Alex Aza Points 29204
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

16 votes

@Derek Smith - la colonne de taille est en pages. La taille d'une page est de 8kB, d'où la formule SizeInMb = PagesCount * 8 / 1024. J'ai toujours cru que 1MB = 1024kB. Je ne pense pas que même Microsoft ait assez de pouvoir pour changer cela :).

1 votes

Cette réponse rapporte les mauvaises valeurs pour tempdb sur notre système pour une raison quelconque. Veuillez consulter cette question connexe .

46voto

Jeffy Points 450

Je ne sais pas exactement ce que vous entendez par efficacité, mais cette solution est simple et fonctionne pour moi :

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

Avec des résultats comme :

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

Note : a été inspiré par cet article

7 votes

J'obtiens des valeurs NULL sur chaque colonne en utilisant cette méthode. Une idée de la raison ?

2 votes

Si sys.master_files est vide, il peut s'agir de permissions. Les permissions minimales sont CREATE DATABASE, ALTER ANY DATABASE, ou VIEW ANY DEFINITION (ref : BOL sys.master_files)

24voto

Chris Halcrow Points 907

Voici une requête simple, rapide et fiable qui donnera tous les noms et tailles des bases de données et des fichiers journaux, ainsi que l'état des bases de données (par exemple ONLINE), dans une sortie agréable et facile à lire :

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

8voto

Garry_G Points 149

Tout cela semble trop compliqué ! Ou est-ce que quelque chose m'échappe ?

Tout ce dont vous avez besoin est quelque chose comme :

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

ou si vous ne voulez pas le journal :

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

7voto

sam Points 27

Avec la taille totale de la base de données commandée 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X