|
提示parallel和parallel_index并不会强制查询优化器使用并行处理,理解这一点很重要。它们会覆盖掉表或索引级别定义的并行度。相应地,这个变化将容许查询优化器考虑是否用指定的并行度来并行处理。查询优化器将考虑有以及没有并行处理的情况,并照常选择开销较低的那个执行计划。
示例如下:
LIBIN@orac>CREATE TABLE t
2 AS
3 SELECT rownum AS id, rpad('*',100,'*') AS pad
4 FROM dual
5 CONNECT BY level <= 100000;
表已创建。
已用时间: 00: 00: 02.95
LIBIN@orac>CREATE INDEX i ON t (id);
索引已创建。
已用时间: 00: 00: 09.20
LIBIN@orac>
LIBIN@orac>execute dbms_stats.gather_table_stats(ownname => user, tabname => 't')
PL/SQL 过程已成功完成。
已用时间: 00: 00: 04.85
LIBIN@orac>DELETE plan_table;
已删除0行。
已用时间: 00: 00: 00.12
查看设置不同的并行度情况下,全表扫描的成本花费
随着并行度的增加,全表扫描的成本成比例地下降
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop1' FOR
2 SELECT /*+ full(t) parallel(t 1) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.14
LIBIN@orac>
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop2' FOR
2 SELECT /*+ full(t) parallel(t 2) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.20
LIBIN@orac>
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop3' FOR
2 SELECT /*+ full(t) parallel(t 3) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.18
LIBIN@orac>
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop4' FOR
2 SELECT /*+ full(t) parallel(t 4) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.03
LIBIN@orac>
LIBIN@orac>SELECT statement_id, cost
2 FROM plan_table
3 WHERE id = 0
4 ORDER BY statement_id;
STATEMENT_ID COST
------------------------------------------------------------ ----------
dop1 350
dop2 194
dop3 129
dop4 97
已用时间: 00: 00: 00.07
例如下面SQL语句,如果SQL语句在没有提示并且并行度为1的情况下执行,查询优化器将选择索引范围扫描。
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop1' FOR SELECT * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.06
LIBIN@orac>SELECT * FROM table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 242607798
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9910 | 1016K| 179 (1)| 00:00:03 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 9910 | 1016K| 179 (1)| 00:00:03 |
|* 2 | INDEX RANGE SCAN | I | 9993 | | 24 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">90000)
已选择14行。
已用时间: 00: 00: 01.78
例如下面SQL语句,如果SQL语句在添加提示并且并行度为2的情况下执行,COSE还是179,查询优化器继续选择索引范围扫描。
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop1' FOR SELECT /*+ parallel(t 2) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.06
LIBIN@orac>SELECT * FROM table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 242607798
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9910 | 1016K| 179 (1)| 00:00:03 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 9910 | 1016K| 179 (1)| 00:00:03 |
|* 2 | INDEX RANGE SCAN | I | 9993 | | 24 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID">90000)
已选择14行。
已用时间: 00: 00: 00.12
例如下面SQL语句,如果SQL语句在添加提示并且并行度为3的情况下执行,COSE是129,查询优化器选择了一个并行的全表扫描.
LIBIN@orac>EXPLAIN PLAN SET STATEMENT_ID 'dop1' FOR SELECT /*+ parallel(t 3) */ * FROM t WHERE id > 90000;
已解释。
已用时间: 00: 00: 00.03
LIBIN@orac>SELECT * FROM table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3050126167
--------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9910 | 1016K| 129 (1)| 00:00:02 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 9910 | 1016K| 129 (1)| 00:00:02 | Q1,00 | P->S | QC (RAND) |
| 3 | PX BLOCK ITERATOR | | 9910 | 1016K| 129 (1)| 00:00:02 | Q1,00 | PCWC | |
|* 4 | TABLE ACCESS FULL| T | 9910 | 1016K| 129 (1)| 00:00:02 | Q1,00 | PCWP | |
--------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("ID">90000)
已选择16行。
已用时间: 00: 00: 00.12 |
|
|