[英]Oracle- Insert query slow
我正在插入:
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 时加载 1k/500 行。
优化器
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
是错误的。 它应该 go 到一个 alter table 语句:
ALTER TABLE mytable NOLOGGING;
ALTER SESSION ENABLE PARALLEL DML;
而不是 nologging,提示应该是APPEND
:
insert /*+ APPEND */ into myTable
select * from myTmpTable;
您的 INSERT 语句非常非常非常慢,因为我在 Linux VM 中使用 Oracle 11.2.0.4 在我的家用 PC 上测试了类似的请求。
我有一个 9 GB 的表(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?别的什么???):我们只能尝试猜测并“在黑暗中射击”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.