删除实时数据库上超过 17 亿行的未索引表(SQL Admin Nightmare)

Posted

技术标签:

【中文标题】删除实时数据库上超过 17 亿行的未索引表(SQL Admin Nightmare)【英文标题】:Dropping an unindexed table with over 1.7 Billion rows on live database (SQL Admin Nightmare) 【发布时间】:2014-06-09 12:56:57 【问题描述】:

我们公司的一位新员工有一个存储过程出现问题,导致大量插入到他的调试表中。该表未编制索引,现在接近 17 亿行,并且占用了太多空间,以至于备份不再适合备份驱动器(备份现在接近 250GB)。

我还没有真正见过这样的事情,所以我在这里寻求 MSSQL 专家的建议。

我知道我可以啃桌子,但是由于没有索引,DELETE FROM [TABLE] WHERE ID IN (SELECT TOP 10000 [ID] FROM [TABLE]) 几乎锁定了搜索它们的服务器。

我也不希望我的日志文件变得庞大,它目前位于 1TB 驱动器上的 480GB。如果我删除这个表,我能把它缩小吗? (我的恢复模式很简单)

我们可以索引表上的 id 字段,虽然我们每天只有大约 9 小时的停机时间,而且在工作时间我们不能锁定数据库。

只是在这里寻求建议,并指出正确的方向。

谢谢。

【问题讨论】:

您将在此处获得此问题的答案,但另外考虑改进您的监控系统。如果在生产时间磁盘空间不足,那可不是什么好玩的时间。 【参考方案1】:

你可以考虑TRUNCATE

MSDN 参考:http://technet.microsoft.com/en-us/library/aa260621(v=sql.80).aspx

从表中删除所有行而不记录单个行删除。

语法:

TRUNCATE TABLE [YOUR_TABLE]

正如@Rahul 在 cmets 中建议的那样,如果您不再打算使用相关表格,您也可以使用 DROP TABLE [YOUR_TABLE]TRUNCATE 选项只会清空表格,但如果您想继续使用它,请将其保留在原处。

关于空间问题,这两个操作都会比较快,并且空间会被回收,但不会立即发生。使用TRUNCATE 时,数据仍然需要删除,但SQL Server 将简单地释放表使用的数据页,并使用后台进程实际执行之后的清理。

This post 应该提供一些有用的信息。

【讨论】:

您没有说是否需要保留表中的任何记录,但如果需要,请先将这些记录复制到新表中,然后按照此处的建议截断该表。然后您可以删除此表并将新表重命名为旧表名。 @HLGEM 他谈到删除和删除表,所以我不认为他想保留任何数据 @HLGEM 刚刚重新阅读您的评论,我不确定它是否针对 OP 而不是我的答案?无论哪种方式,如果需要保留一些记录,这就是要走的路 为什么会和drop table这么不同? drop 如果不再需要该表就可以了【参考方案2】:

一个建议是......只备份那个1.7 billion rows table(可能在磁带驱动器/有足够空间的地方),然后删除表说drop table table_name

这样,如果将来需要调试表数据;你有一个副本,可以从备份中恢复。

【讨论】:

【参考方案3】:

我将删除该表的日志记录并启动一个删除存储过程,该过程将每 1000 行提交一次。

【讨论】:

以上是关于删除实时数据库上超过 17 亿行的未索引表(SQL Admin Nightmare)的主要内容,如果未能解决你的问题,请参考以下文章

mysql在具有1亿行的表上创建索引

Postgres- pgsql 花费更多时间从超过 15 亿行的表中检索数据

在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引

具有超过十亿行的表的 Postgres 性能

如何在超过 100 亿行的海量数据集上执行选择

对包含 2 亿行的 SQL 表进行性能查询?