代码之家  ›  专栏  ›  技术社区  ›  Mark Rogers

事务中的包装插入对Sql Server的性能有多大帮助?

  •  18
  • Mark Rogers  · 技术社区  · 17 年前

    好的,假设我有100行要插入,每行大约有150列(我知道这听起来像是很多列,但我需要将这些数据存储在一个表中)。插入将随机发生(即每当一组用户决定上传包含数据的文件时),大约每月20次。然而,数据库将持续处理大型企业应用程序的其他功能。列是varchar、int以及各种其他类型。

    将这些插入打包到事务中(而不是一次运行一个)的性能增益是巨大的、最小的,还是介于两者之间?

    为什么?

    编辑: 这是针对Sql Server 2005的,但如果有什么不同的话,我会对2000/2008感兴趣。此外,我应该提到的是,我理解事务主要是为了数据一致性,但我想把重点放在性能影响上。

    6 回复  |  直到 17 年前
        1
  •  22
  •   SnapJag    17 年前

    这实际上可能会产生影响。事务的重点不在于你做了多少,而在于保持数据更新的一致性。如果您有需要插入在一起并且相互依赖的行,则这些是您在事务中包装的记录。

    交易是为了保持数据的一致性。这应该是您在使用事务时首先考虑的事情。例如,如果您的支票账户有借记(取款),您需要确保贷记(存款)也已完成。如果其中任何一个都不成功,整个“交易”都应该回滚。因此,这两个操作都必须包含在事务中。

    在进行批量插入时,将它们分解为3000或5000条记录,并在集合中循环。对于插件来说,3000-5000是一个合适的数字范围;除非你已经测试过服务器可以处理它,否则不要超过这个数字。此外,我将大约每3000或5000条记录插入一次go。更新和删除我会把GO设置为大约1000,因为它们需要更多的资源来提交。

    如果你从C#代码中执行此操作,那么在我看来,你应该构建一个批导入例程,而不是通过编码一次执行数百万次插入。

        2
  •  17
  •   undefined    13 年前

    虽然事务是一种保持数据一致性的机制,但如果使用不当或过度使用,它们实际上会对性能产生巨大影响。我刚刚完成了一个 blog post 明确指定事务而不是让它们自然发生对性能的影响。

    如果您要插入多行,并且每次插入都发生在自己的事务中,那么锁定和解锁数据会有很多开销。通过将所有插入封装在单个事务中,您可以显著提高性能。

    相反,如果您对数据库运行了许多查询,并且也发生了大量事务,它们可能会相互阻塞并导致性能问题。

    交易与绩效有着明确的联系,无论其潜在意图如何。

        3
  •  4
  •   kemiller2002    17 年前

    这取决于你所说的“巨大”,但它会有所帮助(这实际上取决于你正在进行的插入的总数)。它将强制SQL Server在每次插入后不进行提交,这会随着时间的推移而增加。插入100次后,根据插入的频率和数据库的其他情况,您可能不会注意到太多的增加。

        4
  •  4
  •   Ken White    17 年前

    正如其他人所说,交易与性能无关,而是与数据的完整性有关。

    话虽如此,当你只谈论每月插入100行数据约20次(即每月2000条记录)时,担心性能是愚蠢的。过早优化是浪费时间;除非您反复测试了这些插件的性能影响(尽管它们很小,也很少见),并发现它们是一个主要问题,否则不要担心性能。与您提到的其他服务器负载相比,这可以忽略不计。

        5
  •  3
  •   Leonidas    17 年前

    事务不是为了性能,而是为了数据完整性。根据实现情况,只有100行的性能不会有任何增益/损失(它们只会被额外记录,因此可以全部回滚)。

    关于性能问题需要考虑的事项:

    • TA将与其他查询进行交互
      • 写入TA将锁定元组/页面/文件
    • 提交可能只是(取决于锁协议)时间戳的更新
    • 可能会为TA编写更多的日志(应该能够回滚TA,但DB可能已经进行了大量日志记录,顺序日志记录的成本很低)
    • 隔离程度(我知道在某些DB中可以切换此级别,但几乎没有人使用级别3)

    总而言之:使用TA来确保完整性。

        6
  •  0
  •   Marius Gri    6 年前

    实际上——极其。对于大型插入,100++(前提是您将mysql配置为增加查询大小和事务大小以支持可怕的查询/事务,对不起,不记得确切的变量名)-插入时间通常可以快10倍,甚至更多