在Oracle中插入2000万行的最快方法

时间:2015-03-24 08:41:51

标签: sql oracle insert migration

我正在尝试从一个oracle数据库迁移到另一个oracle数据库。 我的选择查询非常复杂,它返回大约2000万条记录。 当我尝试执行时:

insert into xxx
select a, b, c, bla blaa
from yyy join zzz join ttt etc

大约需要20个小时。

有什么不同的迁移方式吗? 你能给我一些建议吗?

感谢您的建议。

编辑: 我创建了一个像

这样的新表

创建表XYZ作为从yyy加入zzz join ttt等选择a,b,c,bla blaa

大约需要2分钟。

现在我正尝试从XYZ插入原始表格。

离开15分钟,然后继续:)

我会通知你:))

3 个答案:

答案 0 :(得分:3)

使用SQL查询在数据库之间移动大量数据可能是最差的方法。

如果必须这样做,至少事先转换目标表中的所有约束,它们会在此过程中吸收相当多的CPU。

更好的方法:Oracle为导入/导出和卸载/加载提供实用程序,例如可以找到here

答案 1 :(得分:2)

操作的哪一部分需要花费最多的时间?它是运行原始查询所涉及的工作(返回所有行的时间,而不仅仅是第一行),或者是在数据库之间传输数据的时间(它们是在同一台机器上,还是在同一数据中心的不同机器上,或者在世界的另一端),或者将数据插入表中(既编写数据本身又编写UNDO / REDO?),或者在目标表上维护索引和/或约束(如果有的话)? / p>

一般来说,简单插入... select from ... query将是移动数据的最快方式,除非两者之间的网络连接速度很慢。由于SQL * Net传输中缺乏内在并行性,非常大的数据集可能会出现问题,但通常不计算2000万行。

虽然您可以在那里执行那种优化,但是,SQL * Net会对数据包内发送的数据进行压缩,因此,如果网络时间非常重要,则可能会产生更好的效果通过在SELECT阶段中排序数据进行压缩,ORDER不会显着增加SELECT查询时间,然后可以提高整体性能。但是,你必须考虑所有这些因素。

SELECT查询可能会快速返回初始的几个数据行,但可能无法很好地优化以快速返回所有行。默认情况下,调用SELECT作为INSERT的一部分应该有所帮助,但只有通过运行包含INSERT子句的解释计划,您才有可能知道实际的查询优化计划。

可以使用直接路径插入(APPEND优化器提示)来提高数据插入的速度,但这需要独占锁定,还有一些其他记录的限制。

导出/导入方法需要在源数据库上运行相同的查询,然后磁盘写入和磁盘空间写入文件,然后磁盘读取和网络时间和磁盘写入以迁移它们,然后磁盘空间存储它们在目标机器上,然后磁盘读取以读取文件,然后在目标上使用与insert语句相同的数据插入选项,因此除非您打算使用表空间传输,否则我会考虑这是否真的改进。

这么长的故事简短 - 实际上是什么减慢了流程您是否在源数据库,目标或网络上看到高负载?

答案 2 :(得分:0)

你可以试试这个,首先用你的查询创建一个表,然后插入新创建的表中的行,例如。

create table XYZ as 
select a, b, c, bla blaa
from yyy join zzz join ttt etc

insert into xxx
select a, b, c, bla blaa
from XYZ