今天又加班,憋屈的要死。
正无聊呢,同事过来问我个问题,为什么他通过HINT为查询指定了并行度5,但执行计划里却没有期待中的并行操作。这小子自从听我说了有并行这个东西后,对并行简直着了迷。
原语句如下:
select count(distinct aac001) from ac04;
执行计划显示用到了AAC001字段上的索引,ORACLE为这个语句评估出来的cost是178。
看看采用并行度5的cost是多少。
explain plan for select /*+ full(ac04) parallel(ac04 5) */ count(distinct aac001) from ac04;
发现ORACLE评估出来的cost是431。
并行度5的cost 431> 正常索引的cost 178,因此CBO评估出并行的代价比较大,因此没有采用并行。
我试着加大并行度到10:
explain plan for select /*+ full(ac04) parallel(ac04 10) */ count(distinct aac001) from ac04;
这个时候ORACLE评估出来的cost只有141了。
并行度10的cost 141< 正常索引的cost 178,这个时候应该走并行了吧。
然后我让他按照并行度10进行查询,看看如何,这个时候ORACLE采用了并行查询。
其实大著Troubleshooting Oracle Performance 这本书里对这块有详细的说明the query optimizer
considers execution plans with and without parallel processing and, as usual, picks out
the one with the lower cost:
SQL> EXPLAIN PLAN SET STATEMENT_ID 'dop1' FOR
2 SELECT /*+ full(t) parallel(t 1) */ * FROM t WHERE id > 90000;
SQL> EXPLAIN PLAN SET STATEMENT_ID 'dop2' FOR
2 SELECT /*+ full(t) parallel(t 2) */ * FROM t WHERE id > 90000;
SQL> EXPLAIN PLAN SET STATEMENT_ID 'dop3' FOR
2 SELECT /*+ full(t) parallel(t 3) */ * FROM t WHERE id > 90000;
SQL> EXPLAIN PLAN SET STATEMENT_ID 'dop4' FOR
2 SELECT /*+ full(t) parallel(t 4) */ * FROM t WHERE id > 90000;
SQL> SELECT statement_id, cost
2 FROM plan_table
3 WHERE id = 0
4 ORDER BY statement_id;
STATEMENT_ID COST
------------- -----
dop1 430
dop2 238
dop3 159
dop4 119
可以看到随着并行度的加大,cost在逐渐的变小。再看看正常不加并行的cost
SQL> SELECT * FROM t WHERE id > 9000;
---------------------------------------------------------
| Id | Operation | Name | Cost (%CPU)|
---------------------------------------------------------
| 0 | SELECT STATEMENT | | 178 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| T | 178 (0)|
| 2 | INDEX RANGE SCAN | I | 24 (0)|
---------------------------------------------------------
正常不加并行的cost 178 < 并行度1 和并行度2 时候的cost,因此如果你采用并行度为1或2的时候,并行不会起作用。
SQL> SELECT /*+ parallel(t 2) */ * FROM t WHERE id > 90000;
---------------------------------------------------------
| Id | Operation | Name | Cost (%CPU)|
---------------------------------------------------------
| 0 | SELECT STATEMENT | | 178 (0)|
| 1 | TABLE ACCESS BY INDEX ROWID| T | 178 (0)|
| 2 | INDEX RANGE SCAN | I | 24 (0)|
---------------------------------------------------------
正常不加并行的cost 178 > 并行度3 和并行度4 时候的cost,因此如果你采用并行度为3或4,并行会起作用了。
SQL> SELECT /*+ parallel(t 3) */ * FROM t WHERE id > 90000;
------------------------------------------------------
| Id | Operation | Name | Cost (%CPU)|
------------------------------------------------------
| 0 | SELECT STATEMENT | | 159 (0)|
| 1 | PX COORDINATOR | | |
| 2 | PX SEND QC (RANDOM)| :TQ10000 | 159 (0)|
| 3 | PX BLOCK ITERATOR | | 159 (0)|
| 4 | TABLE ACCESS FULL| T | 159 (0)|
------------------------------------------------------
还有个小tips跟大家分享,如果正常的查询,执行计划中用到了index fast full scan,你如果想使用并行的话,可以通过hint parallel_index来,而不要通过parallel来,后者会选择全表扫描的。而index range scan就没办法了,这个操作是不能并行的,想并行的话貌似只能通过hint parallel,全表扫描来进行并行。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22034023/viewspace-667739/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/22034023/viewspace-667739/