日期:2014-05-18  浏览次数:20516 次

字段字节数变少,保存页数反而增大?
我有个非常大的数据库,数据量大约10亿行左右,20多G,上千个表.为了减小数据量,各表的列都很简略,有:
dt datetime,b numeric(6,2),c int,d bit
其中dt建了一个不具有唯一性的聚集索引.
从数据类型上看,一行的字节数为 8+5+4+1=18字节.
由于dt列占了最长的字节数,于是对它动起了脑筋,因为时间精度只要到分钟,因此想到可以用smalldatetime来替代datetime,它的字节数只有4.
拿其中一个有八十多万行的表做试验,将dt的数据类型改为 smalldatetime,结果发现数据库反而大了一些,以为看错了,再改了几个表,数据库可用空间越来越小,到后来数据库文件也自动增加了.
想不出原因来.
用dbcc checktable检查,当它为datetime数据类型时,第一个表占2708页,可如果改成smalldatetime的话,却占3020页,多占了近三百页哪,10%多!!!
为了检查是不是由于改动而造成的页面增长,将原数据导入到一个没有建索引的空表,导入时把数据类型改小,导入后页数很小,但重建索引后,页数仍然是3020页,可见该索引对该数据类型就得大些.可是,省出来的4个字节哪去了呢?为什么会增加得那么大呢?
是不是我哪儿没考虑到?
还是因为我许久不来CSDN而受到了惩罚?
索引的填充因子为默认值,即0.



------解决方案--------------------
由于dt列占了最长的字节数,于是对它动起了脑筋,因为时间精度只要到分钟,因此想到可以用smalldatetime来替代datetime,它的字节数只有4.
拿其中一个有八十多万行的表做试验,将dt的数据类型改为 smalldatetime,结果发现数据库反而大了一些,以为看错了,再改了几个表,数据库可用空间越来越小,到后来数据库文件也自动增加了.

你去看一下小麦的博客,修改一列字符类型的应该是增加了一列,在原来的基础上

石头大哥,影子老师的也有
------解决方案--------------------
http://blog.csdn.net/happyflystone/archive/2009/12/02/4923803.aspx

参考
------解决方案--------------------
sorry.
可能要显示更新所有行的dt,然后再rebuild clustered index

1).
update tb set dt=CAST(dt as smalldatetime) 

2)
rebuild index....
------解决方案--------------------
正如7樓老大所說 - -
石頭大哥BOLG裏面說的很清楚了
对字符型的列进行修改时,当字节超原来的设定值时,在页面上体现出来的是增加了一列,当修改成小于当初设定值时,页面没有变化。对于整形变化,虽然我们比int变成tinyint了不管是增加还是历史数据仍然点用了int的字节数空间。
順序副石頭大哥的頁面存儲系列-0-
http://blog.csdn.net/happyflystone/archive/2009/12/09/4969909.aspx
http://blog.csdn.net/happyflystone/archive/2009/11/19/4834762.aspx

至於樓主所說單獨新建匯入也會出現更多的頁面,,這個就不知了,,
------解决方案--------------------
这个要看你是怎么修改数据表结构的,如果是使用Alter语句,那么会在原来的表中添加一个新列,这个情况下,数据库文件空间反而会违你所愿的增涨;但如果是通过企业管理器界面中的修改功能,那么则是将整个表做复制删除操作,所以这个情况下,数据库文件空间不会增涨
------解决方案--------------------
探讨

sorry.
可能要显示更新所有行的dt,然后再rebuild clustered index

1).
update tb set dt=CAST(dt as smalldatetime)

2)
rebuild index....

------解决方案--------------------
SQL code
*--压缩数据库的通用存储过程 
  
 压缩日志及数据库文件大小 
 因为要对数据库进行分离处理 
 所以存储过程不能创建在被压缩的数据库中 

--邹建 2004.03(引用请保留此信息)--*/ 

/*--调用示例 
 exec p_compdb  'test ' 
--

------解决方案--------------------
索引的填充因子为默认值,即0

改成100看看
------解决方案--------------------
额。。。这很神,,
以下是我的测试结果
SQL code
 
drop table tb_1
go
create table TB_1(dt datetime,id int,name varchar(20))
go
insert into TB_1 select GETDATE(),1,'adfasdfadsfa'
go 100000
dbcc checktable('tb_1')
--TB_1的 DBCC 结果。
--对象 'TB_1' 的 481 页中有 100000 行。
--DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。
CREATE CLUSTERED INDEX ix_0 ON dbo.tb_1
  (
  dt
  ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
dbcc checktable('tb_1')
--TB_1的 DBCC 结果。
--对象 'TB_1' 的 532 页中有 100000 行。
--DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。


drop table tb
create table TB(dt smalldatetime,id int,name varchar(20))
go
insert into TB select GETDATE(),1,'adfasdfadsfa'
go 100000

dbcc ind(TestDB,tb,-1)
dbcc checktable('tb')