如何使用有限的数据库空间对非常大的表进行分区?

Sto*_*leg 3 sql-server-2008 sql-server partitioning

我有一张很大的桌子。我想分区它,但我不能。

数据库大小:1TB,可用空间200GB

桌子:

  • 大小:165 列(行长 4216 KB,无 LOB),5 亿行,600GB 数据。
  • 可能的分区:每个分区一天
  • 每天/分区的行数:200 万

为了对其进行分区,我需要创建一个聚集索引。但是创建分区需要与表相同大小的可用空间,而我没有额外的600GB。

有什么选项可以让我对这个表进行分区吗?

编辑 1:

我试过将数据复制到单独的表中。

但是,当我尝试DELETE(或INSERT)将 1 天的数据放入另一个表时,出现错误,该事务日志已满并且我的事务正在回滚。我的事务日志大约是 20 GB,我不能让它更大。

mrd*_*nny 5

您需要创建一个具有相同架构的新表,但作为分区对象。您可以选择压缩表格以节省更多空间。由于您平均每页只放置一行,我不确定您会看到多少空间节省。我建议将几千行放入新表中,然后进行压缩,看看节省的空间是否值得 CPU 开销。

至于如何在不占用所有驱动器空间和不增加事务日志的情况下移动这么多数据,则需要在每次运行移动少量数据的循环中完成。您将需要进行一些数据分析以查看您可以处理多大的窗口,但我将根据您需要一次移动行一分钟的数据量假设。

DECLARE @processFrom as datetime
SELECT @processFrom = min(YourDateColumn)
FROM YourTable

DECLARE TABLE @Rows (...)

WHILE EXISTS (SELECT * FROM YourTable)
BEGIN
     DELETE TOP (10000) FROM YourTable
     OUTPUT DELETED.* INTO @Rows
     WHERE YourDateColumn = @processFrom


     INSERT INTO NewTable
     (...)
     SELECT ...
     FROM @Rows

     DELETE FROM @Rows

     IF @@ROWCOUNT = 0
              SET @processFrom = dateadd(dd, 1, @processFrom)
END
Run Code Online (Sandbox Code Playgroud)

当一切都完成并且您已经验证所有数据都在新表中时,删除旧表并重命名新表,使其具有旧表名称。这样没有任何问题。您需要为旧表(如果有)编写权限脚本,以便可以将它们应用到新表。

如果此表中有带有外键的表,您需要先删除它们,然后才能工作。