插入大量行的最快方法是使用并行和直接路径写入:
alter session enable parallel dml;
insert /*+ append parallel */ into test1
select -a, b, c from test;
commit;
(您也许可以简单地使用负号来避免违反主键。ID 几乎总是正数,但通常没有规则阻止它们成为负数。)
此代码不仅仅是一个 FAST=TRUE 标志。您必须首先了解许多重要的注意事项。
并行性需要企业版(最昂贵的版本)、不差的硬件(多于一个内核和一个磁盘)和健全的配置(如果 DBA 设置参数 parallel_max_servers = 1,那么将没有并行可用线程)。并行性通常可以从其他进程中“窃取”——您可能需要 10 倍的系统资源才能仅提高 5 倍的性能。获得正确的并行度可能会很棘手。
Direct-path 直接写入数据文件,并避免写入 REDO 和 UNDO(用于恢复和一致性的额外数据)。这里的权衡是该语句将锁定整个表 - 没有其他人能够同时写入它。并且在下一次完整备份之前,该表将无法恢复。还有很多东西可以阻止直接路径写入,比如触发器、某些外键关系等。
仔细检查执行计划以确保您获得所有功能。您希望看到“LOAD AS SELECT”而不是“LOAD CONVENTIONAL”,以确保您获得直接路径写入。您会希望看到“PX”操作以确保您获得并行性。您需要在读取和操作的写入部分上方都有一个“PX”。仔细检查注释部分,它可能会告诉您为什么没有得到您所要求的。
explain plan for
insert /*+ append parallel */ into test1
select * from test2;
select * from table(dbms_xplan.display);
Plan hash value: 1209398148
----------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 39 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | LOAD AS SELECT (HYBRID TSM/HWMB)| TEST1 | | | | | Q1,00 | PCWP | |
| 4 | OPTIMIZER STATISTICS GATHERING | | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 6 | TABLE ACCESS FULL | TEST1 | 1 | 39 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
----------------------------------------------------------------------------------------------------------------------------
Note
-----
- automatic DOP: Computed Degree of Parallelism is 2
这可能是很多工作!您可能会花费数小时优化单个 INSERT,并且可能需要阅读 Oracle 文档来解决一些问题。但是,如果您有耐心并拥有正确的配置,则可以看到 INSERT 性能的巨大改进。