Friday, March 11, 2011

Things worth to mention and remember (II) - Parallel Execution Control 2

Continuing from the previous installment of this series I'll cover in this post some of the inevitable classics regarding Parallel Execution Control. So forgive me if you're bored by the repetition of known facts - however I still see these things too often used incorrectly, therefore I decided: This is worth to mention and remember!

- Up to and including version 10.2 PARALLEL (without any parameters) and NOLOGGING are valid keywords only in DDL commands

- Applies to all versions: NOLOGGING can not be used as a hint. It can only be specified as part of DDL, for example ALTER INDEX ... REBUILD PARALLEL NOLOGGING.
The only DML operation that can be performed as NOLOGGING operation is a direct-path insert (that can be enabled for parallel DML). For that to work you need to set the NOLOGGING attribute on table / partition level independently from the direct-path insert, in can not be specified as part of the direct-path insert DML command.

- Applies to all versions: For NOLOGGING DDL operations the NOLOGGING keyword needs to be be used at the correct position in the DDL statement:


CREATE TABLE T PARALLEL NOLOGGING AS SELECT ...


A mistake often seen, because it doesn't raise an error in many cases:


CREATE TABLE T PARALLEL AS SELECT ... FROM TAB NOLOGGING


Here NOLOGGING is merely an alias for TAB therefore syntactically correct but not a NOLOGGING operation

Note that most production systems deemed to hold critical data nowadays run in FORCE LOGGING mode anyway (for example due to standby database(s) requiring the full generation of redo), so you probably don't want to bother too much with NOLOGGING anyway.

- Up to and including version 10.2: If you want to use PARALLEL as a hint as part of query / DML statements you need to specify an alias/object_name as parameter, otherwise the hint is invalid. So this is invalid and therefore does nothing:


SELECT /*+ PARALLEL */ ... FROM TABLE T


This is a valid PARALLEL hint for alias T:


SELECT /*+ PARALLEL(T) */ ... FROM TABLE T


You can optionally specify the parallel degree after the alias: PARALLEL(T 16) or PARALLEL(T DEFAULT). If you don't specify a degree DEFAULT will be used which is PARALLEL_THREADS_PER_CPU * CPU_COUNT * INSTANCE_COUNT (not considering additional rules like adaptive multi-user limitations, resource manager plans etc.) and not the (parallel) degree specified on object level (that gets used without any explicit PARALLEL hint).

- Starting with version 11.1 (undocumented) and 11.2 (documented): Release 11g supports now so-called "statement-level" PARALLEL (and NO_PARALLEL) hints, so above invalid syntax IS actually valid from version 11g on which might lead to some interesting side-effects for those that used the hint incorrectly so far and migrate to 11g.

The following rules for statement level PARALLEL hints seem to apply:

- /*+ PARALLEL */ seems to effectively mean PARALLEL(AUTO) (see below) but use at least a degree of 2 for costing and do not consider serial costs for operations that can be run in parallel. The description in the manual seems to be wrong that says that the statement is always executed in parallel. The usual rule applies that a serial plan with a lower cost will be favored if available

- /*+ PARALLEL(DEFAULT) is mentioned in the manual but seems not to be valid in my tests

- /*+ PARALLEL(<degree>) */ Use the defined DOP, where <degree> is integer

- From 11.2 on: /*+ PARALLEL(MANUAL) */ Use the degree defined on object level and therefore seems to be a bit redundant - why use a hint that results in the same as not using the hint (apart from the DISABLE PARALLEL QUERY / PARALLEL hint quirk mentioned here)

- From 11.2 on: /*+ PARALLEL(AUTO) */ Use the auto DOP policy introduced in 11.2 including serial costing of operations that can be run in parallel (the only difference to the "statement level" PARALLEL hint without a parameter I can see)

By the way, the NO_PARALLEL hint can now also be used on "statement level" and seems to effectively prevent PARALLEL and PARALLEL_INDEX costing. It seems to correspond to the (undocumented) hint OPT_PARAM('parallel_execution_enabled', 'false'). By undocumented I mean that this parameter to the recently documented OPT_PARAM hint is not documented officially.

Finally the "statement level" (no)parallel hints override any "object-level" parallel (or no_parallel...) hints.

1 comment: