10

我正在实现A/B/View场景,这意味着View指向表 A,而表 B被更新,然后发生切换,并且在加载表 A 时视图指向表 B。

切换每天发生。有数百万行要更新,成千上万的用户正在查看视图。我在 SQL Server 2012 上。

我的问题是:

  • 如何以最快的方式将数据从另一个表插入到一个表中?(在存储过程中)
  • 有什么方法可以使用 BULK INSERT?或者,是使用常规插入/选择最快的方式吗?
4

6 回答 6

2

我倾向于使用 SSIS。

将表 A 设为 OLEDB 源,将表 B 设为 OLEDB 目标。您将绕过事务日志,从而减少数据库的负载。使用 T-SQL 执行此操作的唯一方法(我能想到的)是更改整个数据库的恢复模型,这远非理想,因为这意味着不存储任何事务,而不仅仅是用于传输的事务。

设置 SSIS 传输

创建一个新项目并将数据流任务拖到您的设计图面上

工具箱菜单

双击您的数据流任务,这将带您进入“数据流”选项卡。然后从“数据流源”菜单拖放一个 OLE DB 源,从“数据流目标”菜单拖放一个 OLE DB 目标

数据流源数据流目的地

双击 OLE DB 源,设置与服务器的连接,选择要从中加载的表,然后单击确定。将绿色箭头从 OLE DB 源拖动到目标,然后双击目标。设置您的连接管理器、目标表名称和列映射,您应该一切顺利。

MSDN 上的 OLE DB 源文档

MSDN 上的 OLE DB 目标文档

于 2012-06-19T12:20:20.513 回答
2

你可以从 SrcTable 中将一个 Select ColA、ColB 放入 DestTable_New。加载 DestTable_New 后,重新创建索引和约束。

然后将 DestTable 重命名为 DestTable_Old 并将 DestTable_New 重命名为 DestTable。重命名非常快。如果结果出现问题,您还可以备份附近的前一个表 (DestTable_Old)。

我曾经做过这种场景,我们必须让系统 24/7 运行并且每天需要加载数千万行。

于 2012-06-19T12:33:45.263 回答
2

你可以这样做

SELECT fieldnames
INTO DestinationTable
FROM SourceTable

正如几个答案所暗示的那样,这应该尽可能快(取决于您需要重新创建多少索引等)。

但我建议使用同义词将指针从一个表更改为另一个表。它们非常透明,在我看来,比更新视图或重命名表更干净。

于 2012-06-19T14:54:56.053 回答
1

我知道这个问题很老,但我一直在寻找同一个问题的答案,但没有发现任何真正有用的东西。是的,SSIS 方法是一种可能性,但问题需要一个存储过程。

令我高兴的是,我(几乎)发现了原始问题想要的解决方案;您可以使用 CLR SP 来完成。

将 TableA 中的数据选择到 DataTable 中,然后使用 SqlBulkCopy 类的 WriteToServer(DataTable dt) 方法,将 TableB 作为 DestinationTableName。

唯一的小缺点是 CLR 过程必须使用外部访问才能使用 SqlBulkCopy,并且不适用于上下文连接,因此您需要稍微调整一下权限和连接字符串。但是,嘿!没有什么是完美的。

于 2016-07-26T06:39:17.470 回答
0

INSERT... SELECT...功能与BULK INSERT. 您可以使用 SSIS,就像@GarethD 说的那样,但是如果您只是将行从 table1 复制到 table2,那可能会过于复杂。

如果您要复制大量数据,请密切注意事务日志——在进行大量插入时,它会迅速膨胀。一种解决方法是“分块”您正在插入的数据,方法是循环处理一次仅处理 100,000 或 10,000 行的插入语句(取决于行的宽度,即每次传递多少 MB)。

(只是好奇,你是在ALTER VIEW重置视图吗?我曾经做过类似的事情,尽管我们必须有四个表和四个视图来支持过去/现在/下一个/交换集。)

于 2012-06-19T13:18:52.820 回答
0

你可以简单地这样做

    select * into A from B Where [criteria]

这将根据条件从 B 中选择数据并将其插入 A,前提是列相同,或者您可以指定列名而不是 *。

于 2012-06-19T13:24:47.857 回答