我正在尝试估计中央数据库服务器的空间需求,该服务器将从大约 200 个相同的现场数据库中收集数据。我有每个表的平均每日行数,现在需要估计每个表的行大小,包括索引。
是否存在这样的动物,还是我需要自己动手?如果我确实需要自己动手,你能提出一个好的方法吗?
TIA
Pav*_*dov 10
被选为 asnwer 的脚本有一些缺点:
不考虑某些 SQL Server 数据类型:
图像、文本、唯一标识符、sql_variant、ntext、hierarchyid、几何、地理、xml、sysname
和 (max) 数据结构结构,例如 varchar(max) 仅举几例。
以下脚本显示记录在数据页上的大小。它显示记录可能占用的最大大小,最小大小(如果表结构允许,则记录中的所有值都为 NULL)。它显示表类型(CLUSTERED/NONCLUSTERED)、数据列总数和表所属的模式。
请注意,此脚本不考虑索引。
更新:脚本将每个位列计算为字节的 1/8。调整最小和最大大小以确保记录不能小于转发存根大小。
SELECT
-- record cannot be smaller than the forwarding stub size =9 Bytes
CASE WHEN [Max Size]>=9
THEN [Max Size]
ELSE 9
END AS [Max Size]
-- record cannot be smaller than the forwarding stub size =9 Bytes
, CASE WHEN [Min Size]>=9
THEN [Min Size]
ELSE 9
END AS [Min Size]
, [Table Name]
, [Table Type]
, [Total Number of Columns]
, [Schema]
FROM
(
SELECT
DISTINCT
-- Overhead for row header of a data row
4
+
-- Overhead for NULL bitmap
2+cast(([Total Number of Columns]+7)/8 AS BIGINT)+
-- overhead for variable length
CASE WHEN [IsVariableLength]>0
THEN
2
ELSE
0
END
+
--- Sum is on record level
SUM(
a1.[max_length]
+
-- Overhead for variable-length columns
CASE WHEN
-- varchar
[System Type]='varchar'
--(([system_type_id]=167) AND ([user_type_id]=167))
OR
-- nvarchar
[System Type]='nvarchar'
--(([system_type_id]=231) AND ([user_type_id]=231))
OR
-- IMAGE
(([system_type_id]=34) OR ([user_type_id]=34))
OR
-- TEXT
(([system_type_id]=35) OR ([user_type_id]=35))
OR
-- NTEXT
(([system_type_id]=99) OR ([user_type_id]=99))
OR
-- SQLVARIANT
(([system_type_id]=98) OR ([user_type_id]=98))
OR
-- hierarchyid geometry geography
(([system_type_id]=240))
THEN 2
ELSE 0
END
)
OVER (PARTITION BY a1.[Schema], a1.[Table Name]) AS [Max Size]
, -- Overhead for row header of a data row
4
+
-- Overhead for NULL bitmap
2+cast(([Total Number of Columns]+7)/8 AS BIGINT)+
-- overhead for variable length
CASE WHEN ([IsVariableLength]>0) AND ([AnyFixedColumn]=0)
THEN
2
ELSE
0
END
+
--- Sum is on record level
SUM(
-- overhead for variable length depending on number of variable columns
CASE WHEN
-- varchar
--[System Type]='varchar'
(([system_type_id]=167) OR ([user_type_id]=167))
OR
-- nvarchar
--[System Type]='nvarchar'
(([system_type_id]=231) OR ([user_type_id]=231))
OR
-- IMAGE
(([system_type_id]=34) OR ([user_type_id]=34))
OR
-- TEXT
(([system_type_id]=35) OR ([user_type_id]=35))
OR
-- NTEXT
(([system_type_id]=99) OR ([user_type_id]=99))
-- VARBINARY
OR
(([system_type_id]=165) OR ([user_type_id]=165))
OR
-- SQLVARIANT
(([system_type_id]=98) OR ([user_type_id]=98))
OR
-- hierarchyid geometry geography
(([system_type_id]=240))
OR
-- xml
(([system_type_id]=241))
THEN
CASE WHEN [Is Nullable]=1
THEN 0
ELSE
1
END
ELSE
CASE
WHEN
-- bit
(([system_type_id]=104) OR ([user_type_id]=104))
and [Is Nullable]=1
THEN 0
ELSE
a1.[max_length]
END
END
--
)
OVER (PARTITION BY a1.[Schema], a1.[Table Name]) AS [Min Size]
, a1.[Table Name]
, [Table Type]
, [Total Number of Columns]
, a1.[Schema]
FROM
-- Start a1
( SELECT
(SELECT [name] FROM [sys].[schemas]
WHERE [sys].[schemas].[schema_id]=[sys].[objects].[schema_id])
AS [Schema]
, [sys].[objects].[name] AS [Table Name]
, [sys].[all_columns].[name] AS [Column Name]
, [sys].[all_columns].[system_type_id]
, (
SELECT name FROM [sys].[types]
WHERE [sys].[types].[system_type_id]=[sys].[all_columns].[system_type_id]
AND
[sys].[types].[user_type_id]=[sys].[all_columns].[user_type_id]
) AS [System Type]
, [sys].[all_columns].[user_type_id]
,
CASE
WHEN
-- IMAGE
(([system_type_id]=34) OR ([user_type_id]=34))
THEN 2147483647
-- TEXT
WHEN (([system_type_id]=35) OR ([user_type_id]=35))
THEN 2147483647
-- NTEXT
WHEN (([system_type_id]=99) OR ([user_type_id]=99))
THEN 1073741823
-- varchar(max)
WHEN (([system_type_id]=167) OR ([user_type_id]=167)) AND ([sys].[all_columns].[max_length]=-1)
THEN 2147483647
-- nvarchar(max)
WHEN (([system_type_id]=231) OR ([user_type_id]=231)) AND ([sys].[all_columns].[max_length]=-1)
THEN 1073741823
-- varbinary(max)
WHEN (([system_type_id]=165) OR ([user_type_id]=165)) AND ([sys].[all_columns].[max_length]=-1)
THEN 2147483647
-- hierarchyid geometry geography
WHEN (([system_type_id]=240))
THEN 2147483647
-- xml
WHEN (([system_type_id]=241) AND ([sys].[all_columns].[max_length]=-1))
THEN 2147483647
-- bit
WHEN (([system_type_id]=104) OR ([user_type_id]=104))
THEN 1/8
ELSE
CAST([sys].[all_columns].[max_length] AS BIGINT)
END [max_length]
, [sys].[all_columns].[is_nullable] AS [Is Nullable]
,
CASE
WHEN EXISTS
(
SELECT type_desc FROM sys.indexes
WHERE type_desc='CLUSTERED'
AND [sys].[objects].[object_id]=[sys].[indexes].[object_id]
)
THEN 'CLUSTERED'
ELSE 'HEAP'
END AS [Table Type]
, COUNT([sys].[all_columns].[name]) OVER (PARTITION BY [sys].[objects].[object_id]) AS [Total Number of Columns]
,SUM (CASE WHEN
-- varchar
(
(([system_type_id]=167) AND ([user_type_id]=167))
OR
-- nvarchar
(([system_type_id]=231) AND ([user_type_id]=231))
)
AND [sys].[all_columns].[is_nullable]=0
THEN 1
ELSE 0
END) OVER (PARTITION BY [sys].[objects].[name]) AS [IsNonNullableVariableLength]
,SUM (
CASE WHEN
-- varchar
(([system_type_id]=167) OR ([user_type_id]=167))
OR
-- nvarchar
(([system_type_id]=231) OR ([user_type_id]=231))
OR
-- IMAGE
(([system_type_id]=34) OR ([user_type_id]=34))
OR
-- TEXT
(([system_type_id]=35) OR ([user_type_id]=35))
OR
-- NTEXT
(([system_type_id]=99) OR ([user_type_id]=99))
-- VARBINARY
OR
(([system_type_id]=165) OR ([user_type_id]=165))
OR
-- SQLVARIANT
(([system_type_id]=98) OR ([user_type_id]=98))
OR
-- hierarchyid geometry geography
(([system_type_id]=240))
OR
-- xml
(([system_type_id]=241))
THEN 1
ELSE 0
END) OVER (PARTITION BY [sys].[objects].[name])
AS [IsVariableLength]
,SUM (
CASE WHEN
-- varchar
(([system_type_id]=167) OR ([user_type_id]=167))
OR
-- nvarchar
(([system_type_id]=231) OR ([user_type_id]=231))
OR
-- IMAGE
(([system_type_id]=34) OR ([user_type_id]=34))
OR
-- TEXT
(([system_type_id]=35) OR ([user_type_id]=35))
OR
-- NTEXT
(([system_type_id]=99) OR ([user_type_id]=99))
-- VARBINARY
OR
(([system_type_id]=165) OR ([user_type_id]=165))
OR
-- SQLVARIANT
(([system_type_id]=98) OR ([user_type_id]=98))
OR
-- hierarchyid geometry geography
(([system_type_id]=240))
OR
-- xml
(([system_type_id]=241))
THEN 0
ELSE 1
END) OVER (PARTITION BY [sys].[objects].[name])
AS [AnyFixedColumn]
FROM [sys].[objects]
INNER JOIN sys.all_columns
ON [sys].[objects].[object_id]=[sys].[all_columns].[object_id]
WHERE type_desc='USER_TABLE'
) a1
) a2
Run Code Online (Sandbox Code Playgroud)
小智 9
使用 Aaron 的链接来更好地适应我的过程,我会推荐一个函数和一个视图/查询来报告每个表每行的大小,包括索引。
create function dbo.getColumnSize (@typeName SYSNAME, @max_length INT, @precision INT)
RETURNS INT
AS
BEGIN
RETURN (SELECT CASE @typeName
WHEN 'tinyint' THEN 1
WHEN 'smallint' THEN 2
WHEN 'int' THEN 4
WHEN 'bigint' THEN 8
WHEN 'numeric' THEN ((@precision - 1)/2) + 1
WHEN 'decimal' THEN ((@precision - 1)/2) + 1
WHEN 'real' THEN 4
WHEN 'float' THEN CASE WHEN @precision <=24 THEN 4 ELSE 8 END
WHEN 'money' THEN 8
WHEN 'smallmoney' THEN 4
WHEN 'time' THEN 5
WHEN 'timestamp' THEN 5
WHEN 'date' THEN 3
WHEN 'smalldatetime' THEN 4
WHEN 'datetime' THEN 8
WHEN 'datetime2' THEN 8
WHEN 'datetimeoffset' THEN 10
WHEN 'char' THEN @max_length
WHEN 'varchar' THEN @max_length + 2
WHEN 'nchar' THEN @max_length
WHEN 'nvarchar' THEN @max_length + 2
WHEN 'binary' THEN @max_length
WHEN 'varbinary' THEN @max_length + 2
WHEN 'bit' THEN 0.125
END)
END
select SchemaName, ObjectName, SUM(CEILING(Bytes))+4+2+2+2+(ceiling(count(distinct columnname)*1.0/8.0)) As RowSize--, FLOOR((POWER(2,30)+(POWER(2,30)-1))*1.0/SUM(CEILING(Bytes))/30/2/60/24)
from (
select s.name as SchemaName, o.name AS ObjectName, c.name as ColumnName, t.name as TypeName
, dbo.getColumnSize(t.name,c.max_length, c.precision) AS Bytes
from sys.objects o
inner join sys.schemas s on s.schema_id=o.schema_id
inner join sys.columns c on o.object_id=c.object_id
inner join sys.types t on c.system_type_id=t.system_type_id
and t.user_type_id=c.user_type_id
where o.type='U'
AND RIGHT(t.name,4) != 'text'
UNION ALL
select s.name as SchemaName, o.name AS ObjectName, c.name as ColumnName, t.name as TypeName
, dbo.getColumnSize(t.name,c.max_length, c.precision) AS Bytes
from sys.objects o
inner join sys.schemas s on s.schema_id=o.schema_id
inner join sys.indexes i on i.object_id = o.object_id
inner join sys.index_columns ic on ic.object_id = o.object_id
and i.index_id = ic.index_id
inner join sys.columns c on o.object_id=c.object_id
and ic.column_id = c.column_id
inner join sys.types t on c.system_type_id=t.system_type_id
and t.user_type_id=c.user_type_id
where o.type='U'
AND RIGHT(t.name,4) != 'text'
) Z
group by SchemaName, ObjectName
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26122 次 |
最近记录: |