在SQL Azure中通过顶层表生成磁盘使用情况的查询?

时间:2013-02-04 11:15:02

标签: sql-server tsql azure-sql-database

我喜欢使用SQL Management Studio报告“顶级表的磁盘使用情况”来查看占用数据库空间的内容。我可以在SQL Azure中使用什么等效查询来查看

  • 每个表的行数
  • 每个表的磁盘使用量(最好是分解数据和索引)

在SQL事件探查器中,我可以看到“顶级表的磁盘使用情况”报告通常运行此命令:

begin try 

    SELECT TOP 1000
        (row_number() over(order by (a1.reserved + ISNULL(a4.reserved,0)) desc))%2 as l1,
        a3.name AS [schemaname],
        a2.name AS [tablename],
        a1.rows as row_count,
        (a1.reserved + ISNULL(a4.reserved,0))* 8 AS reserved,
        a1.data * 8 AS data,
        (CASE WHEN (a1.used + ISNULL(a4.used,0)) > a1.data THEN (a1.used + ISNULL(a4.used,0)) - a1.data ELSE 0 END) * 8 AS index_size,
        (CASE WHEN (a1.reserved + ISNULL(a4.reserved,0)) > a1.used THEN (a1.reserved + ISNULL(a4.reserved,0)) - a1.used ELSE 0 END) * 8 AS unused

    FROM    (   SELECT
                ps.object_id,
                SUM ( CASE WHEN (ps.index_id < 2) THEN row_count    ELSE 0 END ) AS [rows],
                SUM (ps.reserved_page_count) AS reserved,
                SUM (CASE   WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                            ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count) END
                    ) AS data,
                SUM (ps.used_page_count) AS used
                FROM sys.dm_db_partition_stats ps
                GROUP BY ps.object_id
            ) AS a1

    LEFT OUTER JOIN (   SELECT
                        it.parent_id,
                        SUM(ps.reserved_page_count) AS reserved,
                        SUM(ps.used_page_count) AS used
                        FROM sys.dm_db_partition_stats ps
                        INNER JOIN sys.internal_tables it ON (it.object_id = ps.object_id)
                        WHERE it.internal_type IN (202,204)
                        GROUP BY it.parent_id
                    ) AS a4 ON (a4.parent_id = a1.object_id)

    INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id )

    INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)

    WHERE a2.type <> N'S' and a2.type <> N'IT'

end try
begin catch
    select
    -100 as l1
    ,   1 as schemaname
    ,       ERROR_NUMBER() as tablename
    ,       ERROR_SEVERITY() as row_count
    ,       ERROR_STATE() as reserved
    ,       ERROR_MESSAGE() as data
    ,       1 as index_size
    ,       1 as unused
end catch

但在使用消息

对SQL Azure运行时失败
Msg 208, Level 16, State 1, Line 4
Invalid object name 'sys.internal_tables'.

3 个答案:

答案 0 :(得分:10)

编辑2016年5月24日:这些天似乎不起作用......我将不得不重做这个

嗯,我想因为它是sys.internal_tables这就是问题,最简单的方法是从混合中删除它。稍作调整,我们留下了这个:

 SELECT TOP 1000
        a3.name AS SchemaName,
        a2.name AS TableName,
        a1.rows as Row_Count,
        (a1.reserved )* 8.0 / 1024 AS reserved_mb,
        a1.data * 8.0 / 1024 AS data_mb,
        (CASE WHEN (a1.used ) > a1.data THEN (a1.used ) - a1.data ELSE 0 END) * 8.0 / 1024 AS index_size_mb,
        (CASE WHEN (a1.reserved ) > a1.used THEN (a1.reserved ) - a1.used ELSE 0 END) * 8.0 / 1024 AS unused_mb

    FROM    (   SELECT
                ps.object_id,
                SUM ( CASE WHEN (ps.index_id < 2) THEN row_count    ELSE 0 END ) AS [rows],
                SUM (ps.reserved_page_count) AS reserved,
                SUM (CASE   WHEN (ps.index_id < 2) THEN (ps.in_row_data_page_count + ps.lob_used_page_count + ps.row_overflow_used_page_count)
                            ELSE (ps.lob_used_page_count + ps.row_overflow_used_page_count) END
                    ) AS data,
                SUM (ps.used_page_count) AS used
                FROM sys.dm_db_partition_stats ps
                GROUP BY ps.object_id
            ) AS a1

    INNER JOIN sys.all_objects a2  ON ( a1.object_id = a2.object_id )

    INNER JOIN sys.schemas a3 ON (a2.schema_id = a3.schema_id)

    WHERE a2.type <> N'S' and a2.type <> N'IT'   
    order by a1.data desc         

Azure提供了一些有趣的management views and functions,但在这种情况下不需要......我想。

答案 1 :(得分:6)

尝试查询sys.dm_db_partition_stats

如,

- 计算各个数据库对象的大小。

SELECT sys.objects.name, SUM(reserved_page_count) * 8.0 / 1024 as Size
FROM sys.dm_db_partition_stats, sys.objects 
WHERE sys.dm_db_partition_stats.object_id = sys.objects.object_id 
GROUP BY sys.objects.name
ORDER BY Size DESC;
GO

答案 2 :(得分:0)

这是一个在 SQL 2012 上运行的函数,它具有与报告基本相同的数据。基于之前的答案并稍微扩展。

它被封装在一个 SP 中,允许针对服务器上的任何数据库调用它,因此您不需要它的 20 个副本。

注释掉您不想要的任何单位大小。 GB 对我很有用。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE dbo.TableSizes

    @DB varchar(50) = 'OP'
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
   
    -- DECLARE @DB AS varchar(50)='OP'; -- DEBUG LINE

    DECLARE @sql nvarchar(max)='
    WITH A AS (
        SELECT Sc.name AS SchemaName, O.name AS TableName
            , SUM(ps.row_count) AS TotalRows
            , CAST(SUM(ps.reserved_page_count) * 8.0 / 1024 / 1024 AS Decimal(28,6)) AS TotalSizeGB
            , CAST(SUM(ps.used_page_count) * 8.0 / 1024 / 1024 AS Decimal(28,6)) AS UsedTotalSizeGB
            , CAST(SUM(ps.reserved_page_count) * 8.0 / 1024 AS Decimal(28,3)) AS TotalSizeMB
            , CAST(SUM(ps.used_page_count) * 8.0 / 1024 AS Decimal(28,3)) AS UsedTotalSizeMB
            , CAST(SUM(ps.reserved_page_count) * 8.0 AS Decimal(28,0)) AS TotalSizeKB
            , CAST(SUM(ps.used_page_count) * 8.0 AS Decimal(28,0)) AS UsedTotalSizeKB
            --, O.Type
        FROM $DB$.sys.dm_db_partition_stats AS PS
            JOIN $DB$.sys.objects AS O ON PS.object_id=O.object_id
            JOIN $DB$.sys.schemas AS Sc on O.schema_id=Sc.Schema_id
        WHERE O.Type=''U'' -- user tables only
        GROUP BY Sc.name, O.name
            --, O.Type
    )
    SELECT A.*
        , CASE WHEN A.TotalSizeGB=0 THEN NULL ELSE 100.0 * A.UsedTotalSizeGB / A.TotalSizeGB END AS UsedPercent
    FROM A
    ORDER BY A.TotalSizeGB DESC
    '
    SET @sql=replace(@sql,'$DB$',@DB);

    EXEC sp_executesql @sql;

    -- EXEC Agent.TableSizes 'Scorecards' -- DEBUG LINE

END
GO