2011-07-22 105 views
2

有人知道我可以找到这些东西的链接吗?我正在研究一个建议,从几张表中删除大量未使用的列,如果我能够找出所使用的磁盘空间量,那确实会帮助我。SQL列使用多少磁盘空间

例如,如果我有一个550万行的表,如果我放下BIT/INT32/DECIMAL(18,2)列,我将节省多少空间?

这是SQL Server 2008.

再次感谢!

+0

我会说“创建数据库的副本,从有问题的表中删除列,然后取大小差异”,但如果数据库很大,可能会有些不可行。 – JAB

+0

是的,这是我的后备计划。我遇到的问题是我们的“开发”数据库是我们生产的数据库的一个削减版本;发展的曲调是1 GB,而实际的产量接近5或6 GB –

回答

2

列与实际记录分配有很大差异。

对于类型:

但在现实世界中的列进行分组一些排列规则记录。记录由大页面分配,可以包含一千个记录。磁盘空间也受到事务日志的影响 - 部分保存了一些记录。所以很难推断出列大小的线性相关性。

1

这是每行

对于数学运算:

tinyint 1 byte 
smallint 2 bytes 
int  4 bytes 
bigint 8 bytes 

Bit是穿过记录汇总,所以很难不知道你的结构说。这不太可能节省很多。

DECIMAL将取决于精度:

1 - 9 5 bytes 
10 - 19 9 bytes 
20 - 28 13 bytes 
29 - 38 17 bytes 
2

这片SQL的越过你的所有列,并为您的datalength()的总和。

我意识到这不完全是OP所要求的 - 这是为可怜的人谁的谷歌“SQL服务器列空间使用”的好处,并找到这个问题。

它也在my gist here

create table #space ([table] nvarchar(255), [column] nvarchar(255) not null, [bytes] bigint null); 

declare @sql varchar(max) = '' 
declare @tablepattern as varchar(255) = '%' 
declare @exclusionpattern as varchar(255) = '' 

select @sql = @sql + 'insert into #space select ''' + t.name + ''', ''' + c.name + ''', sum(datalength([' + c.name + '])) as bytes from [' + t.name + '];' 
from sys.columns c 
inner join sys.tables t on c.object_id = t.object_id 
where t.name like @tablepattern and t.name not like @exclusionpattern; 

exec (@sql) 

select [table], format(sum([bytes]), '#,#') as [size] 
from #space 
group by [table] 
order by sum(bytes) desc; 

select [table], [column], format([bytes], '#,#') as [size] 
from [#space] 
order by [bytes] desc; 

drop table #space