SQL插入大型数据集

3
当运行像“insert into table”这样的查询时,我们如何处理提交大小?即,另一个表中的所有记录是否在单个事务中插入,还是有一种方法可以设置提交大小?
感谢您的提问。请注意,本站点非常适合初次使用者。

对于新手,请尽量避免在问题中添加不必要的元素。可以适当利用评论部分进行补充。 :) 一点一点地积累,最终成就一个字节。 - Suvarna Pattayil
12个回答

3
在好的数据库中,这是一个原子语句,因此无法限制插入记录的数量 - 这是一件好事!

3

如果原帖作者想要避免回滚空间问题,答案就很简单。回滚段的大小应该根据事务的大小来确定,而不是反过来。当你的事务完成时,再提交。


2
我曾经用过各种语言编写代码,主要是Java,来进行像您描述的批量插入。每次我都是从解析某些输入文件或类似的东西开始,基本上只需准备一部分要插入的数据(通常是4000个左右的批次),然后将这些数据提供给我们的DAO层。所以这是通过程序完成的。我们从未注意到以这种方式执行操作会有任何真正的性能损失,而且我们处理了数百万条记录。如果您需要插入大型数据集,则无论如何执行操作,它都会“花费一些时间”。

1

除非您明确编写代码,否则无法处理提交大小。例如,您可以使用where循环,并编写一种限制所选数据量的方法。


但是对于大型插入,这通常是次优的。 - Bob Probst
不确定为什么这个答案会被踩,因为它是正确的。 - Nick Pierpoint
我也不明白,尼克从来没有理解它。 - JoshBerke

1

David Aldridge是正确的,根据最大事务大小来调整回滚段大小,当您希望INSERT作为一个整体成功或失败时。

一些替代方案:

如果您不关心能否回滚(这就是该段存在的原因),则可以使用ALTER TABLE并添加NOLOGGING子句。但除非您正在加载报告表并删除所有旧行并加载新行,或者其他特殊情况,否则这不是明智之举。

如果您可以接受某些行插入而其他行由于某种原因失败,则可以添加支持处理故障的语法INSERT INTOLOG ERRORS INTO


0

我想这样做的原因是为了避免回滚段空间不足。此外,我希望能够定期查看目标表中的结果。

我不想使用where循环,因为它可能会增加性能开销。不是吗?

~ Sri


由于回滚段是Oracle的一个特性,因此您应该在问题中打上“oracle”的标签。 - Bill Karwin
我认为这个网站的预期做法是,您应该编辑原始问题并提供任何进一步的信息,因为随着其他答案被投票,它们可能会潜在地丢失。 - RSlaughter
你能将这个作为对原问题的修改添加吗? - David Aldridge
@sri 这不是一个答案,应该作为评论或编辑您的原始问题。 - schmidlop

0

你说得对,你可能想要分批运行大量插入操作。附上的链接展示了在SQL Server中执行此操作的方法,如果你使用不同的后端,你需要做类似的事情,但确切的语法可能会有所不同。这是一个可以接受循环的情况。

http://www.tek-tips.com/faqs.cfm?fid=3141


0
“我想这么做的原因是为了避免回滚段空间不足。此外,我希望能够定期查看目标表中的结果。”
“第一个问题只需要正确设置撤销表空间大小即可。由于撤销是对现有行的删除,所以不需要太多的空间。相反,删除通常需要更多的空间,因为它必须拥有整个被删除行的副本以便在需要时重新插入。”
“至于第二个问题,可以查看v$session_longops和/或v$sql中的rows_processed。”

0
如果您需要限制数据集,请将该限制构建到查询中。
例如,在Microsoft SQL Server术语中,您可以使用“TOP N”来确保查询仅返回有限数量的行。
INSERT INTO thisTable
  SELECT TOP 100 * FROM anotherTable;

0
INSERT INTO TableInserted
SELECT *
FROM (
   SELECT  *,
          ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber
   FROM TableSelected
) X
WHERE RowNumber BETWEEN 101 AND 200

你可以很容易地将上述内容包装到一个while循环中,用变量替换101和200。这比一次处理一条记录要好。

我不知道哪些版本的Oracle支持窗口函数。


返回翻译后的文本:-1因为这是一个非常慢的方法。 对于一个包含10万条记录的表,您要访问1000次“TableSelected”,每次访问很可能都是一次完整的表扫描... - Rob van Wijk
你假设它总是表扫描。好的,把数据放到临时表中。你有更好的方法吗?我在这里没有看到。 - Lurker Indeed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接