我正在将大量数据从文本文件加载到SQL Server中。目前,每个记录都在一个单独的事务中插入(或更新),但如果记录失败,则会使DB处于错误状态。
我想把它全部放在一次大交易中。在我的情况下,我正在查看~250,000个插入或更新,可能还有~1,000,000个查询。文本文件大约是60MB。
将整个操作放入一个交易是不合理的吗?限制因素是什么?
答案 0 :(得分:12)
这样做不仅没有道理,但如果你想在任何记录失败的情况下保持完整性,这是必须的,所以你得到一个“全有或全无”的导入。对于SQL来说,250000插入或更新将没有问题,但我会看看这些百万个查询是什么。如果他们不需要执行数据修改,我会将它们从事务中删除,因此它们不会减慢整个过程。
当你有一个打开的事务(无论大小)时,你必须考虑到它所触及的表会发生外观,而像你这样的冗长交易可能会导致其他用户试图阻止同时读取它们。如果您希望导入过大且耗时且系统负载不足,请考虑在整个过程中(或任何非高峰时段)进行整个过程以减轻影响。
关于大小,SQL Server中没有特定的大小限制,理论上它们可以毫无问题地修改任何数量的数据。实际限制实际上是目标数据库的事务日志文件的大小。事务正在进行时,数据库引擎将所有临时数据和修改数据存储在此文件中(因此可以根据需要使用它将其回滚),因此该文件的大小将会增大。它必须在数据库属性中有足够的可用空间,并且文件有足够的高清空间来增长。此外,引擎将放在受影响的表上的行或表锁会消耗内存,因此服务器也必须有足够的可用内存用于所有这些管道。无论如何,60MB的大小通常太少而不用担心。 250,000行是相当可观的,但也不是那么多,所以任何体面的服务器都能够处理它。
答案 1 :(得分:3)
SQL Server可以处理这些大小的事务。我们使用单个事务批量加载数百万条记录。
数据库操作中最昂贵的部分通常是客户端服务器连接和流量。对于插入/更新,索引和日志记录也很昂贵,但您可以通过使用正确的加载技术来降低这些成本(请参阅下文)。您确实希望限制客户端和服务器之间传输的连接数量和数据。
为此,您应该考虑使用SSIS或C#与SqlBulkCopy批量加载数据。批量加载所有内容后,您可以在服务器上使用基于集合的操作来更新或验证您的数据。
请查看此问题,以获取有关优化数据加载的更多建议。这个问题与C#有关,但很多信息对SSIS或其他加载方法很有用。 What's the fastest way to bulk insert a lot of data in SQL Server (C# client)。
答案 2 :(得分:0)
个人而言,我并没有将导入的数据直接加载到我的产品表中,而是我清除了所有记录,这些记录在我到达加载点之前很久就没有通过。某些类型的错误会完全阻止导入,而其他错误可能只是将记录发送到异常表,以便发送回提供程序并在下次加载时进行修复。通常我有逻辑确定是否有太多异常并且也会杀死包。
例如,假设城市是数据库中的需要字段,并且在1,000,000条记录的文件中,您有10个没有城市。最好将它们发送到异常表并加载其余的表。但假设您有357,894条记录没有城市。然后,您可能需要与数据提供者进行对话,以便在加载之前修复数据。如果在尝试影响生产表之前可以确定文件不可用,那么肯定会影响prod。
另外,你为什么要一次做这一条记录?基于集合的处理通常可以更快地完成,特别是如果您已经设法事先清理数据。现在你可能仍然需要批量生产,但一次只能创建一条记录。
如果你真的想要回滚整个事情,如果任何部分错误,是的,你需要使用交易。如果您在SSIS中执行此操作,那么您可以将事务放在包中影响prod表的部分,而不必担心它们在数据的分段和清理部分中。
答案 3 :(得分:0)
执行全部或全部批量操作没有问题,除非完全回滚对您的业务有问题。事实上,单个事务是许多批量插入实用程序的默认行为。
我强烈建议不要每行一次操作。如果要清除坏数据,可以先将数据加载到临时表中,然后以编程方式确定“坏数据”并跳过这些行。