【问题标题】:Inserting a large table into a new table (SQL)将大表插入新表 (SQL)
【发布时间】:2019-01-11 17:28:46
【问题描述】:

我有一个非常大的 SQL Server 表(2.2 亿条记录),大小为 233GB。我需要将此表导出到一个平面文件中,并通过 Putty 将其发送到另一台服务器,该服务器将直接将此表插入数据仓库。

此数据仓库具有如何加载数据的特定架构(每列的特定数据类型和长度)。

首先,我需要通过更改 SQL Server 中列的数据类型和数据长度来进行一些验证。我使用alter table 更改数据类型和数据长度,但最终出现错误。所以我试图将该表插入到一个新表中,同时在那些应该坚持数据仓库模式的列上使用SUBSTRINGCAST 函数。

由于事务日志文件驱动器和 TempDB 驱动器中的空间限制,这是不可能的。我现在完全没有希望了。任何完成此任务的替代解决方案将不胜感激。

【问题讨论】:

  • 你能在数据库上创建视图吗?如果是,则转换视图中的数据并将数据从视图而不是表格复制到平面文件。
  • @GrzegorzGrabek 从未尝试过或想过。让我现在试一试

标签: sql sql-server


【解决方案1】:

我还在有限的空间里使用一张这种大小的大桌子。有几种方法可以解决它。但是您必须小心,您可能会因为物理空间不足而遇到错误,这可能会导致 SQL 崩溃。执行这些操作时,请密切注意磁盘可用空间和日志文件大小及其增长速度。取消任何可能导致磁盘用尽的操作(最好在您越过不归路之前,因为取消过程也需要时间)。我要检查的第一件事是,您的数据库恢复模型设置为完整还是简单?设置为 Simple 有助于减少日志记录和使用宝贵的临时空间。

当您处理非常有限的空间时,您当然需要注意数据库和日志文件的大小。我知道我要提出的建议通常不受欢迎,但有时这是不可避免的。在尝试下一个解决方案时,尝试使用 DBCC SHRINKFILE() 使 DB 和日志文件尽可能低。确保正确计算 DB 实际使用了多少空间,并留出一点填充空间。

--Check free space in a file
USE DMS_DataCompare;
SELECT name ,size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS AvailableSpaceInMB
FROM sys.database_files;


USE tempdb
DBCC SHRINKFILE (tempdev,1)

DBCC SHRINKFILE (templog,1)

USE Master;
DBCC SHRINKFILE (N'MASTER',10000)

DBCC SHRINKFILE (N'MASTER_log',NOTRUNCATE)

解决此问题的一种方法是逐列。可以删除之前数据表的任何部分吗?如果是这样,您可以添加与您尝试迁移到的架构具有相同规格的列,然后使用 UPDATE 将数据从旧列复制到新列,然后删除旧列,然后执行收缩文件。冲洗并重复。

要尝试的另一件事是,是否有任何数据列包含您不需要的数据?你可以将它们清空,做一个收缩文件,这将恢复一些宝贵的移动空间。

另一种方式是评论者发布的内容,设置视图以强制数据通过您需要的数据类型和大小。我认为你应该先试试这个,因为它使整个过程只读,所以你不会弄乱文件大小和日志记录。您还可以编写一个类似于视图的过程,该过程接受两个参数,启动和停止,可用于指定要拉取的范围。然后可以在导出步骤中使用它。

正如 user1443098 发布的那样,批量导出,不是作为一个过程,而是作为一个简单的脚本。但这可能很难跟踪,尤其是在尝试导出平面文件时,因为您可能很快就会迷失在哪个文件中包含的确切范围,可能会根据它所包含的范围命名您的文件。如果您的数据当前处于活动状态且不断变化,则此选项可能无用。

另一种选择是备份数据库并将其恢复到有空间的机器上。通过备份压缩后,数据库备份的大小可以是正常大小的 1/10(如果您有支持此功能的 SQL 版本)。

另一个是上述两种情况的组合。使用目标规范创建一个表,然后编写一个脚本以从旧表插入到新表中,但要分批。在每批之后,从旧表中删除相同的范围,然后做一个收缩文件。确保首先验证所有数据已成功复制到新表中!不过,这个过程可能会非常漫长,因为所涉及的每个步骤都需要时间。

希望这有帮助,祝你好运!

【讨论】:

  • 哦,这是很多信息。谢啦。会让你知道哪一个对我有用。
【解决方案2】:

分批插入新表,比如一次插入 1000,000 行。这将帮助您控制 tempdb 和日志的使用

【讨论】:

  • 我也试过了。即使要拆分该数据,它也需要 TempDB 驱动器中的更多空间。
  • 不要在 SQL 中拆分数据。在您用于插入数据的程序中,一次读取(从平面文件)某些部分(例如 100.000 行),插入这些部分,然后提交。然后执行接下来的 100,000 行等直到完成
  • 我忘了提这个。我不是从平面文件中导入这个大表。该表是通过在 SQL 中连接另外两个表来创建的。
  • 所以你的问题出在这一步? “我需要将此表导出到平面文件中”然后您可以使用在不同服务器上运行的 SSIS 来执行此操作(以免用完您的 tempdb)或者只是获得更多的 tempdb 空间。
猜你喜欢
  • 1970-01-01
  • 2011-12-03
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2021-11-24
  • 1970-01-01
相关资源
最近更新 更多