我有一个场景,每个用户都分配了2 MB的数据库空间。 现在我必须显示Percenatge对其分配空间的使用情况,为此我需要知道表中单个记录的大小。
我曾尝试使用sp_spaceused甚至编写了一个使用datalength的自定义过程..但是它们的结果显示出巨大的差异。
有没有办法让这件事情做对。
答案 0 :(得分:25)
答案 1 :(得分:12)
以下查询将通过查看数据库对象分配的页数来告诉您数据正在使用的@SpaceAllotted的百分比。
尝试在行级别测量使用率是不值得的,因为SQL Server会在范围级别分配所有空间。每个范围由8个8KB数据页组成。因此,如果您的数据库只有一行,并且该行有4个字节的数据,则仍需要分配整个范围来保存该4个字节(或者将使用具有未分配页面的现有范围。这称为混合范围)。
DECLARE @SpaceAllotted FLOAT
-- 2MB converted to kilobytes...
SET @SpaceAllotted = 2048
SELECT
-- Allocation is done on the extent-level.
-- Each extent contains eight 8KB data pages.
((1 / (@SpaceAllotted)) * CEILING(CAST(SUM([ips].[page_count]) AS FLOAT) / 8) * 64) * 100 AS PercentageUsed
FROM
[sys].[dm_db_index_physical_stats](DB_ID(), NULL, NULL, NULL, NULL) ips
-- This will allow us to retrieve the page count of all tables in the
-- current database, regardless of whether or not they have clustered
-- indexes and/or non-clustered indexes.
INNER JOIN
[sys].[indexes] i
ON
[ips].[object_id] = [i].[object_id]
AND [ips].[index_id] = [i].[index_id]
由于我们确实有混合扩展区的可能性,并且没有良好的方式(有方法,但它们不会很漂亮)确定哪些页面被分配到哪个范围,这个不是100%准确。此外,扩展区甚至可能具有空闲页面(保留页面,因此仍占用磁盘空间),因此通常,此估计值总是很低。但是,如果没有在页面级别编写检查数据库的内容,它可能是最好的。
啊,是的,看看其他答案,这是另一种选择。这基本上将查看页面中数据文件的所有当前大小,并确定它们消耗的空间百分比。现在,这里也有一些警告......
希望其中一个解决你的问题。
SELECT
((1 / CAST(SUM([df].[max_size]) AS FLOAT)) * CAST(SUM([df].[size]) AS FLOAT)) * 100 AS PercentUsed
FROM
[sys].dm_io_virtual_file_stats(DB_ID(), NULL) vfs
INNER JOIN
[sys].[database_files] df
ON
[vfs].[file_id] = [df].[file_id]
WHERE
[df].[type] = 0
答案 2 :(得分:12)
由于showcontig将被弃用,您还可以使用:
SELECT * FROM sys.dm_db_index_physical_stats
(DB_ID(N'DatabaseName'), OBJECT_ID(N'TableName'), NULL, NULL , 'DETAILED')
答案 3 :(得分:10)
您可以使用相当复杂的公式计算行(行数)的大小。有关详细信息,请参阅Books Online(ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.en/udb9/html/81fd5ec9-ce0f-4c2c-8ba0-6c483cea6c75.htm)。
简而言之:
获取列数并根据固定长度数据类型的数据类型确定每列的大小。
计算用于任何可空列的空间 然后计算行空间:
Row_Size = Fixed_Data_Size + Variable_Data_Size + Null_Bitmap + 4
答案 4 :(得分:1)
数据保存在磁盘上为数据库命名的目录中。这包括一切,包括你没有测量的东西(指数等)。衡量一下。