日期:2014-05-17  浏览次数:20558 次

对表删除了大量的数据,为什么数据库文件没减小?按理说至少要减少5G
对表删除了大量的数据,为什么数据库文件没减小?按理说至少要减少5G,
我们这个表的数据有43G,为什么对里面的数据删除了1/5,为什么数据库文件没减少
2次都是在缩收过数据库之后对比.是不是表空间还要单独释放什么的?
不知道如何做?

------解决方案--------------------
SQL code
--11.收缩数据库

--1.自动收缩数据库:将AUTO_SHRINK 数据库选项设置为ON 后,数据库引擎将自动收缩具有可用空间的数据库。作用相当于DBCC SHRINKDATABASE(dbname,25).默认情况下,此选项设置为OFF。

--2.手动收缩数据库:可以使用DBCC SHRINKDATABASE 语句或DBCC SHRINKFILE 语句来手动收缩数据库或数据库中的文件。

/*1.在该过程中任意时间都可停止DBCC SHRINKDATABASE 和DBCC SHRINKFILE 操作,所有已完成工作都将保留。

  2.在使用DBCC SHRINKDATABASE 语句时,您无法将整个数据库收缩得比其初始大小更小。

  3.使用DBCC SHRINKFILE 语句时,可以将各个数据库文件收缩得比其初始大小更小。必须对每个文件分别进行收缩,而不能尝试收缩整个数据库。

*/

DBCC SHRINKDATABASE 

( database_name | database_id | 0 

 [ , target_percent ] 

 [ , { NOTRUNCATE | TRUNCATEONLY } ] 

)

[ WITH NO_INFOMSGS ]

会收缩一个数据库的所有文件.数据库不能收缩到比model数据库还小,并且DBCC SHRINKDATABASE 也不能将一个文件收缩到比其最小的大小还小.

其中target_percent参数是数据库中每个文件所保留的自由空间的百分比.

比如:如果我用 DBCC SHRINKDATABASE(dbname,25) 其中一个总大小为MB文件的其中MB的数据库文件,可以保留%的可用空间,那么新的文件

 大小为MB。怎么算出来的呢?x*1.0/(x+60)=25% x=20 所以总的大小为用掉的MB 加上空闲的MB 一共为MB。

 如果文件是用掉了MB,那收缩还剩多少呢?x*1.0/(x+80)=25% x>20 注意这里x+80>100 这样超过了总大小,所以这个时候改文件不发生收缩,保持原来的大小.

    所以整个数据库就是以这个方式逐个收缩数据库.

    

    DBCC SHRINKFILE 

(

{ file_name | file_id } 

{ [ , EMPTYFILE ] 

| [ [ , target_size ] [ , { NOTRUNCATE | TRUNCATEONLY } ] ]

}

)

[ WITH NO_INFOMSGS ]

其中的target_size 用兆字节表示的文件大小(用整数表示)。如果未指定,则 DBCC SHRINKFILE 将文件大小减少到默认文件大小。默认大小为创建文件时指定的大小。

这里只要注意不能将文件收缩到比存储数据所需空间还小.

例如:你的数据库文件一共MB,用了MB,那么你只能收缩到>=8MB的大小,即使你target_size=7mb,最后文件大小还是MB

 

你也许会发现这里有几个选项可选:

1.NOTRUNCATE:在指定或不指定 target_percent 的情况下,将已分配的页从数据文件的末尾移动到该文件前面的未分配页。文件末尾的可用空间不会返回给操作系统,文件的物理大小也不会更改。

因此,指定 NOTRUNCATE 时,文件看起来未收缩。NOTRUNCATE 只适用于数据文件。日志文件不受影响。

2.TRUNCATEONLY:将文件末尾的所有可用空间释放给操作系统,但不在文件内部执行任何页移动。数据文件只收缩到最后分配的区。

如果随 TRUNCATEONLY 指定了 target_size,则会忽略该参数。TRUNCATEONLY 只适用于数据文件。

3.EMPTYFILE:将指定文件中的所有数据迁移到同一文件组中的其他文件。只适合DBCC SHRINKDATABASE

 

--例子:截断数据库

DBCC SHRINKDATABASE (dbname, TRUNCATEONLY);

--例子:将数据文件收缩到指定的目标大小

DBCC SHRINKFILE (dbname, 7);

--例子:将日志文件收缩到指定的目标大小

-- 将数据库的恢复模式设置为SIMPLE

ALTER DATABASE dbname

SET RECOVERY SIMPLE;

GO

-- 收缩你的日志文件到MB

DBCC SHRINKFILE (dbname_log,3);

GO

--重新设置回你的恢复模式

ALTER DATABASE AdventureWorks

SET RECOVERY FULL;

GO

--例子:清空文件

-- 首先创建一个文件(举例而已)

ALTER DATABASE AdventureWorks 

ADD FILE (

NAME = Test1data,

FILENAME = 'C:\t1data.ndf',

SIZE = 5MB

);

GO

-- 转移你的数据库文件到该文件组的其他文件

DBCC SHRINKFILE (Test1data, EMPTYFILE);

GO

-- 移除你的数据库文件

ALTER DATABASE AdventureWorks

REMOVE FILE Test1data;

GO

------解决方案--------------------
收缩数据库
------解决方案--------------------
还得收缩数据库 另外看一下数据文件的初始分配空间是多大
------解决方案--------------------
SQL code
select   obj.[name],
[size(KB)]=(row_data.data_pages+isnull(lob_data.lob_pages,0))*8
from
(select [object_id],data_pages=sum(total_pages)
from sys.allocation_units a inner join sys.partitions p
on a.[type] in (1,3) and a.container_id=p.hobt_id group by [object_id]) row_data
left join
(select [object_id],lob_pages=sum(total_pages)
from sys.allocation_units a inner join sys.partitions p
on a.[type]=2 and a.container_id=p.partition_id group by [object_id]) lob_data
on row_data.[object_id]=lob_data.[object_id]
inner join
(select [object_id],[name] from sys.objects where [type]='U') obj
on row_data.[object_id]=obj.[object_id]
order by [size(KB)] desc

------解决方案--------------------
删了之后全备份,然后日志就可以干掉了,再收缩数据库应该有效果的
------解决方案--------------------
重启一把数据库看还有多大,如果肯定可以减少很多空间的。排除TEMP占用。