我们有一个大约有100个索引的表。因此,当我尝试向该表插入大量行时,执行插入需要花费太多时间。我尝试了PARALLEL和APPEND提示,但没有多大帮助。
在这种情况下,还有其他方法可以提高插入性能吗?(我不想禁用触发器然后又启用)使用解释计划来确保你正确使用了追加和并行提示——这些提示出错的方式有很多。
下面是一个很好的大型数据仓库语句解释计划的示例:
create table test1(a number);
explain plan for
insert /*+ append parallel enable_parallel_dml */ into test1
select 1 from test1;
select * from table(dbms_xplan.display);
Plan hash value: 1209398148
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------------
| 0 | INSERT STATEMENT | | 1 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 1 | 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 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
| 5 | PX BLOCK ITERATOR | | 1 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 6 | TABLE ACCESS FULL | TEST1 | 1 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------------
Hint Report (identified by operation id / Query Block Name / Object Alias):
Total hints for statement: 1 (U - Unused (1))
---------------------------------------------------------------------------
0 - STATEMENT
U - parallel
Note
-----
- dynamic statistics used: dynamic sampling (level=2)
- automatic DOP: Computed Degree of Parallelism is 2
对于良好的并行直接路径性能,这些是在explain计划中要寻找的主要内容:
- 确保使用直接路径写。加载为选择;表示追加提示有效,"INSERT conventional";说明没有使用提示。不能使用直接路径有许多可能的原因,其中最常见的原因是未启用并行DML,这就是第三个提示所做的。(在12c之前,您必须运行
alter session enable parallel dml
) - 确保读和写都是并行的。应该有一个"PX"在"LOAD AS select"之前和之后的操作。如果之前没有操作,那么写操作不是并行完成的。
- 确保并行度是正确的解释计划将告诉您所请求的并行度。DOP是很难得到正确的,并受到许多因素的影响。如果您的DOP似乎有问题,请使用此清单查找可能的问题。
如果仍然有问题,请使用SQL监视报告查找有关实际执行计划、行、时间和等待事件的信息。生成报告通常像select dbms_sqltune.report_sql_monitor('your SQL_ID') from dual
一样简单。如果你把结果贴在这里,有人可能会找到提高性能的方法。