【问题标题】:Synchronizing tables - does order of UPDATE INSERT DELETE matter?同步表 - UPDATE INSERT DELETE 的顺序是否重要?
【发布时间】:2013-10-09 06:45:44
【问题描述】:

我需要每天在两个数据库之间同步表,源是 MSSQL 2008,目标是 MSSQL 2005。如果我使用 UPDATE、INSERT 和 DELETE 语句(即 UPDATE 更改的行、INSERT 新行、DELETE 行不再现在),如果我先执行 DELETE 语句会不会有性能提升?也就是说,UPDATE 语句不会查看不需要更新的行,因为它们将被删除。

这是我需要考虑的其他一些事情。这些表有 1-3 百万+ 行,并且由于事务量和业务需求,源 DB 需要保持在线,并且查询需要尽可能高效。该作业将每天在目标数据库上的 SQL Server 代理作业中运行。最重要的是,我是一名 DB 菜鸟!

感谢 StackOverflow 社区,你们太棒了!

【问题讨论】:

  • 我会说 DELETE 然后 UPDATE 然后 INSERT,但不一定出于性能原因。 (1) 删除将可能释放稍后可能被插入使用的空间 (2) 如果您先执行插入,您可能更新这些行之后执行更新。
  • 谢谢亚伦伯特兰!

标签: sql sql-server sql-server-2008 tsql sql-server-2005


【解决方案1】:

我会说,首先您执行delete,然后执行update,然后执行insert,因此您不必更新无论如何都会被删除的行,也不会更新刚刚插入的行。

但实际上,你见过 SQL Server merge 语法吗?它可以为您节省大量代码。

更新我没有检查 MERGE 语句对 INSERT/UPDATE/DELETE 的性能,这里是 Aaron Bertrand 提供的相关 link 以获得更多详细信息。

【讨论】:

  • 我建议不要合并。您的代码的总字符数可能会更短,但 lots of potential pitfalls.
  • @AaronBertrand 谢谢,就在我说合并之后,我意识到我从未检查过性能,所以必须编辑答案并阅读您的链接
  • @AaronBertrand 我赞同你对合并可靠性的看法。另一方面,您在测试期间没有遇到任何错误或发现它们的机会非常高。我们现在距离它推出已经 5 年了 - 我希望清除常见的错误,并解散原始开发人员。我认为合并从 OP 同步代码中删除了一些三重冗余的事实比错误引入的错误更多。
  • 我认为由于该作业将在 2005 年的目标机器上运行,因此合并不是一个选项。 stackoverflow.com/questions/12621241/…
  • @usr 不同意,“三重冗余”涉及自 SQL Server 6.x 以来已经尝试过且真实的模式,并且并非所有错误(或某些情况下的性能缺陷)都是不正确的结果错误这在测试期间必然是显而易见的。我知道至少有 15 个仍然处于活动状态或按设计关闭/无法修复的错误,我已经写了一篇关于此的警告文章,即将发布。
【解决方案2】:

经验法则:DELETE,然后是UPDATE,然后是INSERT

抛开性能不谈,我主要关心的是在以下情况下避免任何潜在的死锁

  1. 更新您将立即删除的内容。
  2. 插入一些您可能会立即尝试更新的内容。

如果您只修改必要的内容并正确使用交易,那么您可以使用任何订单。
附言有人建议使用MERGE - 我已经尝试了几次,我的偏好是永远不要使用它。

【讨论】:

    【解决方案3】:

    我认为 Roman 的答案是您在当前情况下所寻找的:DELETE、UPDATE、INSERT(或 MERGE)。

    现在还有其他可能的路线可以让事情变得更快,但过程却截然不同:

    1。考虑将所有订单保存在一个文件中,您偶尔会针对目标运行该文件

    假设两个数据库完全相同,对于修改 2008 数据库的每个 SQL 顺序,将该顺序保存在 .sql 文件中,稍后您将针对 2005 数据库执行该文件。您必须考虑在写入文件时锁定文件,并且可能存在某种冗余。但是,这意味着您在处理 2005 数据库时根本不需要访问 2008 数据库。换句话说,对 2008 年的数据库速度没有副作用。

    陷阱:您可能会错过一个语句,并且目的地不会是完全等价的......

    2。持续复制

    我对 MSSQL 的了解不足以告诉您进行自动复制的好工具(请参阅此处:http://technet.microsoft.com/en-us/library/ms151198.aspx),但我敢打赌,您可以找到一个好工具。 MySQL (http://dev.mysql.com/doc/refman/5.0/en/replication.html) 和 PostgreSQL (http://wiki.postgresql.org/wiki/Streaming_Replication) 都有这样的工具,而且都是免费的。

    这将是我会选择的解决方案。根据您使用的工具,它可以得到很好的优化,这意味着对实时系统的影响将是最小的,并且 2005 副本将在几秒钟内更新(取决于它是否是长距离远程连接,工作量、每台服务器的设置、互联网连接等)

    明显的缺陷是它在数据库上添加了一个持续的进程,但是如果你发现一个 MSSQL 工具的工作方式类似于 PostgreSQL 的流式复制,它会使用日志的副本,这意味着它很快就会死掉(不大量使用磁盘 I/O。)

    3。集群数据库(如 Cassandra)

    这将涉及更改数据库,我完全确定您还没有准备好这样做(尤其是因为这些系统中的大多数不提供 SQL),但我认为在你的情况。

    像 Cassandra (http://cassandra.apache.org/) 这样的系统会自动在多台计算机上复制其数据。它实际上可以设置为每台计算机复制所有数据 100% 或 X% 的数据,并在出现故障(计算机发生故障)时具有冗余。这减少了对单独计算机上特定副本的需求,因为只需在系统中添加几个节点即可提高性能。 (一台计算机不到 1,000 美元,物有所值!坦率地说,您可以以 5 万美元或更少的价格创建一个 Peta Byte 系统,并最终得到比任何 SQL 数据库都快得多的东西......)

    主要问题是这些集群的使用与 SQL 完全不同。但这对于拥有大型数据库的大型企业来说可能是一个解决方案,这些大型数据库需要非常快,并且他们不想投资小型计算机(想想 Cobol 和价值 25 万美元的计算机,它们可以在几毫秒内管理 1 亿行...... .)

    使用 Cassandra,您可以在不影响前端系统的后端计算机上运行极其繁重的批处理!

    【讨论】:

    • 谢谢,这很有帮助。我已经开始查看第一条路线,保存到文件中。事后看来,我相信考虑到这种情况,这将是理想的选择。我真的只需要每天更新一次,所以有些差异是允许的。
    • 至于你提到的第二条路线,我们确实讨论过这个问题,但由于数据库上的负载波动,因此决定正在进行的活动是不可取的。
    • 第三个选项是我会研究的。看起来是一个有吸引力的选择,我将与开发人员讨论一些事情。谢谢你,亚历克西斯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2013-10-25
    • 1970-01-01
    相关资源
    最近更新 更多