我在做一个插入式的作为。
insert /*+ NOLOGGING */ into myTable
select /*+ parallel(3) */ * from myTmpTable;
这里解释一下计划。
------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 110M | 5776M| 91428(2)| 00:03:30 | | | |
| 1 | LOAD TABLE CONVENTIONAL | myTable | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM) | :TQ10000 | 110M | 5776M| 91428(2)| 00:03:30 | Q1,00 | P->S | QC (RAND) |
| 4 | PX BLOCK ITERATOR | | 110M | 5776M| 91428(2)| 00:03:30 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL | myTmpTable | 110M | 5776M| 91428(2)| 00:03:30 | Q1,00 | PCWP | |
------------------------------------------------------------------------------------------------------------------------------------
myTmpTable总共有110M的行,并且myTable的pk已经设置在临时故事中。
当我运行查询时,我已经看到在FULL ACCES期间,当达到60M时,性能明显下降,它在开始加载5M时,每次加载1k500行。
优化器
NAME TYPE VALUE
------------------------------------ ------- --------
optimizer_capture_sql_plan_baselines boolean FALSE
optimizer_dynamic_sampling integer 2
optimizer_features_enable string 11.2.0.4
optimizer_index_caching integer 0
optimizer_index_cost_adj integer 100
optimizer_mode string ALL_ROWS
optimizer_secure_view_merging boolean TRUE
optimizer_use_invisible_indexes boolean FALSE
optimizer_use_pending_statistics boolean FALSE
optimizer_use_sql_plan_baselines boolean TRUE
编辑
这里是执行一部分2M(或多或少)后的统计。
Total For Execution For Row
Executions 1 1 <0.01
Time Elapsed(sec) 22.862,82 22.862,82 0,01
Time CPU(sec) 673,69 673,69 <0.01
Buffer Requests 26.019.084 26.019.084 12,70
Disk Reads 3.073.558 3.073.558 1.50
Direct 0 0 0,00
Rows 2.0048.853 2.0048.853 1
FETCH 0 0 0
我认为 NOLOGGING
是错误的。应该转到 alter table 语句。
ALTER TABLE mytable NOLOGGING;
ALTER SESSION ENABLE PARALLEL DML;
而不是nologging,提示应该是: APPEND
:
insert /*+ APPEND */ into myTable
select * from myTmpTable;
你的INSERT语句是 非常非常慢 因为我在家里的电脑上用Linux虚拟机中的Oracle 11.2.0.4测试了一个类似的请求。
我有一个9GB的表(134M行),我可以在不并行的情况下复制11分钟。
OPS$ORACLE@FTEX>explain plan for insert into nt select * from t;
Explained.
OPS$ORACLE@FTEX>select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1601196873
---------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 134M| 9472M| 402K (1)| 01:20:28 |
| 1 | LOAD TABLE CONVENTIONAL | NT | | | | |
| 2 | TABLE ACCESS FULL | T | 134M| 9472M| 402K (1)| 01:20:28 |
---------------------------------------------------------------------------------
9 rows selected.
OPS$ORACLE@FTEX>set timing on
OPS$ORACLE@FTEX>insert into nt select * from t;
134217728 rows created.
Elapsed: 00:11:16.40
OPS$ORACLE@FTEX>commit;
但如果不使用... 实行计划 不可能知道时间花在哪里(CPU?IO?其他东西??):我们只能尝试猜测和 "在黑暗中拍摄"。