我试图找到示例,但是使用单个where子句它们都很简单。情况就是这样。我从另一个数据库传输了一堆遗留数据。我在同一个数据库中也有“好”的表。我需要将(数据转换)数据从遗留表传输到w表。因为这是一组不同的表,所以数据转换需要复杂的连接才能将旧数据正确地放入新表中。
所以,旧表旧数据。
新表必须包含旧数据,但需要大量连接才能将旧数据正确地存入新表中。
我可以使用这样的大量连接的直接路径吗? INSERT SELECT(大量连接) 直接路径是否适用于已在同一数据库中的表(表之间的传输)?它只用于从表示文本文件加载表吗?
谢谢。
答案 0 :(得分:2)
SELECT中的查询可能与直接路径插入一样复杂。直接路径仅指目标表。它与读取或处理数据的方式无关。
如果您正在进行直接路径插入,那么您要求Oracle在表格的高水位线上方插入新数据,以便绕过在现有块中重用空间的常规代码,以便插入新行。它还必须阻止其他插入,因为在直接路径插入期间不能使表的高水位变化。如果您有一个停机窗口来执行加载,这可能不是什么大问题,但如果您希望现有表在加载期间可用于其他应用程序,则可能会出现问题。
答案 1 :(得分:2)
不,相反,这意味着您需要在NOLOGGING加载后进行备份,而不是无法备份数据库。
请允许我详细说明一下。通常,当您在Oracle中执行DML时,您正在进行的更改的前映像将登录到UNDO,并且所有更改(包括UNDO更改)将首先写入REDO。这就是Oracle管理事务,实例恢复和数据库恢复的方式。如果事务被中止或回滚,Oracle将使用UNDO中的信息撤消事务所做的更改。如果实例崩溃,那么在实例重启时,Oracle将使用REDO和UNDO中的信息来恢复到最后一次提交的事务。首先,Oracle将读取REDO并前滚,然后使用UNDO回滚崩溃时未提交的所有事务。通过这种方式,Oracle能够恢复到最后一次提交的事务。
现在,当您在insert语句上指定APPEND提示时,Oracle将直接加载执行INSERT。这意味着数据从高水位线上方加载到全新的,从未使用过的块中。因为正在加载的块是全新的,所以没有“之前的映像”,因此,Oracle可以避免编写UNDO,从而提高性能。如果数据库处于NOARCHIVELOG模式,那么Oracle也不会写REDO。在ARCHIVELOG模式的数据库中,Oracle仍将编写REDO,除非在执行insert / * + append * /之前,将表设置为NOLOGGING(即alter table tab_name nologging;)。在这种情况下,表的禁用REDO日志记录。但是,您可能会遇到备份/恢复问题。如果您执行NOLOGGING直接加载,然后您遇到介质故障,和包含带有nologging操作的段的数据文件将从nologging加载之前的备份中恢复,那么重做日志将< em> not 包含恢复该段所需的更改。那么,会发生什么?好吧,当您执行NOLOGGING加载时,Oracle会将范围内值记录写入重做日志,而不是实际更改。然后,如果您在恢复中使用该重做,那么这些数据块将被标记为逻辑损坏。针对该段的任何后续查询都将收到ORA-26040错误。
那么,如何避免这种情况?好吧,你应该在任何NOLOGGING直接加载后立即进行备份。如果您在 nologging加载后从备份中恢复/恢复,则没有问题,因为数据将位于已还原文件的数据块中。
希望很清楚,
-Mark
答案 2 :(得分:1)
是的,对查询复杂性不应有任何限制。
如果你这样做 插入/ * + APPEND * /进入target_table select .... from source1,source2 ...,sourceN where
应该可以正常工作。但请注意,负载的性能将受到该查询性能的限制,因此,如果您期望获得良好的性能,请确保它已经过良好调整。
最后,考虑在目标表上设置NOLOGGING是否会显着提高性能。但是,如果您决定实施NOLOGGING,还要考虑备份恢复的影响。
希望有所帮助,
-Mark