2017-09-27 58 views
2

我有一个相当大的数据库(高达几百张分片日表,总共1.3TB的mdf文件)。SQL Server将“表空闲空间”移动到“数据库空闲空间”

现在,我们希望尽力阻止mdf进一步增长,我们会从现有表中删除尽可能多的不必要数据。

我们知道:

  1. 从表中删除数据并不能降低MDF文件的大小。
  2. 缩小文件/数据库是不成问题的。
  3. 从旧表(例如table_20161231)删除不释放新表的数据库的空间(如table_20170927),除非旧表被重建。

所以我们理解一个表重建是必要的,改变索引似乎没有帮助,根据“exec sp_spaceused”的结果,空间仍然没有释放。

因此,我们现在正在做如下:

  1. 从table_20161231其中数据= '不必要' 删除;
  2. 选择*到table_20161231_compact从table_20161231
  3. DROP TABLE table_20161231

执行“EXEC注释sp_spaceused”似乎再次具有了新表多了很多“未分配空间”,显示阳性结果。

有没有人知道1行方法来释放删除的数据的空间?

+0

>>>从旧表删除(比如说table_20161231)不会释放新的表空间数据库< <<你是从堆中删除还是从簇表中删除? – sepupic

+0

@sepupic,你问的问题似乎超出了我的理解,我只是从非常简单的表格中删除非常简单,我怎么知道你需要知道什么? –

+0

很简单。在SSMS中编写脚本并查看它是否具有CLUSTERED索引。如果一个表没有CLUSTERED索引,那就是一堆。请检查它,这很重要,因为如果不是在某些条件下堆不释放可用空间 – sepupic

回答

0

当您从表中删除时,SQL Server会保留该空间以重复使用,因为它假定它最终会被填充。如果你想要它,不幸的是推卸责任是唯一的方法。它可以充满危险,但作为一个你知道数据不会回到那个大小,你照顾索引碎片后,它应该是好的...

你已经做到这一点的方式是可能是最安全的方法,您可以编写脚本并使用sp_rename来更改表名称。

迈克·沃尔什的确,当你缩小HERE

+0

嗯,我们希望避免收缩,因为这是一个实时生产数据库,每秒都有很多事务处理,我们希望尽量减少需要做一些占用大量资源的东西,例如HD IO .. –

+0

@dbajtr OP的问题不在于释放OS的空间,他从堆中删除,并且它们不释放空间给**数据库**,免费删除后页面仍然分配给堆。 – sepupic

0

所以,如果你堆删除会发生什么像样的博客。堆不释放空间,如果你只是删除行,可能的解决方法是创建群集索引或删除tablock

Deleting Rows by Using DELETE

删除从堆行时行从堆删除数据库引擎可能使用行或页面锁定操作。作为 结果,由删除操作使空的页仍保留为堆分配 。当空白页未被释放时,相关的 空间不能被数据库中的其他对象重新使用。要删除堆中的 行并释放页面,请使用以下方法之一。

  • 在DELETE语句中指定TABLOCK提示。使用TABLOCK提示会导致删除操作在表
    上取得共享锁而不是行或页面锁。这允许页面被解除分配
    。有关TABLOCK提示的更多信息,请参阅表
    提示(Transact-SQL)。
  • 如果要从表中删除所有行,请使用TRUNCATE TABLE。
  • 在删除行之前在堆上创建聚簇索引。删除行后,您可以删除聚集索引。此方法
    比以前的方法耗费更多时间,并使用更多的临时资源

以防万一,如果你不知道如何在这里使用tablock是一个例子:

delete dbo.myTbl with(tablock) 
where... 

附:

因此,我们现在正在做如下:

delete from where data = 'unnecessary'; 
select * into table_20161231_compact from table_20161231 
drop table table_201table_2016123161231 

有谁知道1号线的方法来释放出被删除的数据的空间?

是的,它可以在1个命令完成开始与SQL Server 2008:

alter table table_20161231 rebuild