我想在我的选择查询中使用并行提示来提高性能。但是这个select语句在from子句中包含多个表。如何在select语句中使用并行提示?
INSERT INTO /*+APPEND */ ITEM
(
)
SELECT a FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
UNION
SELECT a FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
在11g之前,必须为每个需要并行性的表提供提示。从11g开始,您可以省略表别名,并将单个并行提示应用于整个语句。Oracle会自己决定什么应该并行化,什么不应该并行化,通常它会倾向于并行化几乎所有的东西。在可能的情况下,指定的度数将用于所有对象。这仅仅是:
INSERT /*+ APPEND PARALLEL(16) */ INTO ITEM
(
)
SELECT a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
UNION
SELECT a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
请记住,并行提示将应用于选择部分,而不是插入部分,因为这需要启用并行dml (ALTER SESSION ENABLE PARALLEL DML
或提示enable_parallel_dml
)。所以要并行化整个过程包括插入的块加载步骤,你需要:
INSERT /*+ APPEND PARALLEL(16) enable_parallel_dml */ INTO ITEM
(
)
SELECT a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
UNION
SELECT a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
最后,请注意,我将您的提示向后移动了一个单词,在关键字INSERT
之后。Oracle只查找SQL块的初始关键字后面的提示。
关于选择DOP(并行度,在本例中为16),有几个因素需要考虑:
1. What is the parallel_max_servers
2. Is parallel_degree_policy = manual or auto?
3. If auto, what is parallel_degree_limit set to?
4. Has the DBA overridden hints with optimizer_ignore_parallel_hints?
5. How many CPU cores are on the host(s) the database is mounted on?
6. How many others sessions might be using how many parallel slaves at the same time?
7. Is there a DBRM (Resource Manager) rule defined that caps DOP for your consumer group?
8. How big are the tables you are scanning or joining?
由于这一切的复杂性,最好直接询问您的DBA该系统的推荐配置。如果使用太多,可能会导致数据库出现问题。我建议从4个开始,如果有足够的资源,只在需要时增加。数字8和16并不特殊,它们只是程序员之间的惯例。
假设您的PARALLEL_MAX_SERVERS
值为80。然后你可以使用它:
INSERT INTO /*+APPEND */ ITEM
(
)
SELECT /*+ PARALLEL(p, 8) PARALLEL(r, 16) */ a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
UNION
SELECT /*+ PARALLEL(p, 8) PARALLEL(r, 16) */ a
FROM GTT_LINE p, GTT_LINE_XY r
Where <condition>
注意:8
和16
之和不能超过80
的最大值。要检查最大值,您必须以SYS或SYSDBA身份登录并运行下一个命令:
SELECT name, value FROM v$parameter WHERE name IN ('parallel_max_servers', 'parallel_execution_enabled');