oracle 谓词推入失效,【案例】Oracle优化之优化SQL时遇到连接谓词推入不成功分析...

【案例】Oracle优化之优化SQL时遇到连接谓词推入不成功分析

时间:2016-11-04 19:31   来源:Oracle研究中心   作者:HTZ   点击:

天萃荷净

Oracle研究中心案例分析:运维DBA反映在做Oracle SQL优化时遇到连接谓词推入不成功情况,在测试环境中进行判断。

今天在客户现场优化SQL时遇到连接谓词推入不成功,由于但是客户正式环境不允许操作,测试环境又是10G环境,没有办法测试,下面是在自己的VM里面测试。

1,环境介绍

本次实验是基于11.2.0.4环境,其它环境在默认情况下可能结果会不一致。

oracleplus.net> select * from v$version where rownum<4;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE    11.2.0.4.0      Production

Elapsed: 00:00:00.00

oracleplus.net> set timing off

oracleplus.net> select * from v$version where rownum<4;

BANNER

--------------------------------------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

PL/SQL Release 11.2.0.4.0 - Production

CORE    11.2.0.4.0      Production

oracleplus.net> !lsb_release -a

LSB Version:    :core-3.0-amd64:core-3.0-ia32:core-3.0-noarch:graphics-3.0-amd64:graphics-3.0-ia32:graphics-3.0-noarch

Distributor ID: RedHatEnterpriseAS

Description:    Red Hat Enterprise Linux AS release 4 (Nahant Update 8)

Release:        4

Codename:       NahantUpdate8

2,参数配置

下面参数都为默认情况下的配置

oracleplus.net> SELECT a.ksppinm AS parameter,

2         b.ksppstvl AS session_value,

3         c.ksppstvl AS instance_value,

4         a.ksppdesc AS description

5  FROM   x$ksppi a,

6         x$ksppcv b,

7         x$ksppsv c

8  WHERE  a.indx = b.indx

9  AND    a.indx = c.indx

10  AND    a.ksppinm LIKE '/_%' ESCAPE '/'

11  AND    (a.ksppinm in ('_push_join_predicate','_optimizer_push_pred_cost_based','_optimizer_extend_jppd_view_types'))

12  ORDER BY a.ksppinm

13  /

PARAMETER                           S_VALUE   D_VALUE  DESCRIPTION

----------------------------------- -------   -------- ----------------------------------------------------------------

_optimizer_extend_jppd_view_types   TRUE      TRUE     join pred pushdown on group-by, distinct, semi-/anti-joined view

_optimizer_push_pred_cost_based     TRUE      TRUE     use cost-based query transformation for push pred optimization

_push_join_predicate                TRUE      TRUE     enable pushing join predicate inside a view

3,创建测试表

这里都是基于dba_objects视图创建的。

oracleplus.net> create table scott.htz1 as select * from dba_objects;

oracleplus.net> create table scott.htz2 as select * from dba_objects;

oracleplus.net> create table scott.htz3 as select * from dba_objects;

4,语句一测试

下面这个SQL还回是0行,其实出view,SQL本来也就是还回0行,这个还回的行数直接影响到我们的测试结果。

SELECT *

FROM scott.htz1 a,

scott.htz2 b,

(  SELECT COUNT (*) COUNT, owner

FROM scott.htz3 c

WHERE c.object_id > 1000

GROUP BY owner) d

WHERE     a.owner = b.owner

AND a.object_id > b.object_id

AND b.CREATED > SYSDATE - 1

AND a.owner = d.owner;

4.1 默认情况

oracleplus.net> SELECT *

FROM scott.htz1 a,

scott.htz2 b,

(  SELECT COUNT (*) COUNT, owner

FROM scott.htz3 c

WHERE c.object_id > 1000

GROUP BY owner) d

WHERE     a.owner = b.owner

AND a.object_id > b.object_id

AND b.CREATED > SYSDATE - 1

AND a.owner = d.owner;

no rows selected

Execution Plan

----------------------------------------------------------

Plan hash value: 2675592091

-------------------------------------------------------------------------------------

| Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |      |    42M|    17G|       |  1447   (9)| 00:00:18 |

|*  1 |  HASH JOIN           |      |    42M|    17G|  2408K|  1447   (9)| 00:00:18 |

|*  2 |   HASH JOIN          |      |  5771 |  2333K|       |   692   (1)| 00:00:09 |

|*  3 |    TABLE ACCESS FULL | HTZ2 |    14 |  2898 |       |   346   (1)| 00:00:05 |

|   4 |    TABLE ACCESS FULL | HTZ1 | 99677 |    19M|       |   345   (1)| 00:00:05 |

|   5 |   VIEW               |      | 88109 |  2581K|       |   348   (2)| 00:00:05 |

|   6 |    HASH GROUP BY     |      | 88109 |  2581K|       |   348   (2)| 00:00:05 |

|*  7 |     TABLE ACCESS FULL| HTZ3 | 88109 |  2581K|       |   345   (1)| 00:00:05 |

-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."OWNER"="D"."OWNER")

2 - access("A"."OWNER"="B"."OWNER")

filter("A"."OBJECT_ID">"B"."OBJECT_ID")

3 - filter("B"."CREATED">SYSDATE@!-1)

7 - filter("C"."OBJECT_ID">1000)

Note

-----

- dynamic sampling used for this statement (level=2)

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

2480  consistent gets

0  physical reads

0  redo size

2554  bytes sent via SQL*Net to client

512  bytes received via SQL*Net from client

1  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

0  rows processed

这里看到整个SQL逻辑读是2480,也消耗了TEMPSPC为2408K.

4.2 强制连接列谓词推入

oracleplus.net> SELECT /*+ push_pred(d)*/

2        *

3    FROM scott.htz1 a,

4         scott.htz2 b,

5         (  SELECT COUNT (*) COUNT, owner

6              FROM scott.htz3 c

7             WHERE c.object_id > 1000

8          GROUP BY owner) d

9   WHERE     a.owner = b.owner

10         AND a.object_id > b.object_id

11         AND b.CREATED > SYSDATE - 1

12         AND a.owner = d.owner;

no rows selected

Execution Plan

----------------------------------------------------------

Plan hash value: 1009835727

--------------------------------------------------------------------------------

| Id  | Operation               | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------------

|   0 | SELECT STATEMENT        |      |    42M|    16G|  1990K  (1)| 06:38:11 |

|   1 |  NESTED LOOPS           |      |    42M|    16G|  1990K  (1)| 06:38:11 |

|*  2 |   HASH JOIN             |      |  5771 |  2333K|   692   (1)| 00:00:09 |

|*  3 |    TABLE ACCESS FULL    | HTZ2 |    14 |  2898 |   346   (1)| 00:00:05 |

|   4 |    TABLE ACCESS FULL    | HTZ1 | 99677 |    19M|   345   (1)| 00:00:05 |

|   5 |   VIEW PUSHED PREDICATE |      |     1 |    13 |   345   (1)| 00:00:05 |

|*  6 |    FILTER               |      |       |       |            |          |

|   7 |     SORT AGGREGATE      |      |     1 |    30 |            |          |

|*  8 |      TABLE ACCESS FULL  | HTZ3 |   881 | 26430 |   345   (1)| 00:00:05 |

--------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("A"."OWNER"="B"."OWNER")

filter("A"."OBJECT_ID">"B"."OBJECT_ID")

3 - filter("B"."CREATED">SYSDATE@!-1)

6 - filter(COUNT(*)>0)

8 - filter("OWNER"="A"."OWNER" AND "C"."OBJECT_ID">1000)

Note

-----

- dynamic sampling used for this statement (level=2)

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

2480  consistent gets

0  physical reads

0  redo size

2554  bytes sent via SQL*Net to client

512  bytes received via SQL*Net from client

1  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

0  rows processed

这里消耗的逻辑读也是2480,但是tempspc为0.但是这里ORACLE自己估算出来谓词推入成本更高。

4.3 连接列创建索引

oracleplus.net> SELECT /*+ push_pred(d)*/

2        *

3    FROM scott.htz1 a,

4         scott.htz2 b,

5         (  SELECT COUNT (*) COUNT, owner

6              FROM scott.htz3 c

7             WHERE c.object_id > 1000

8          GROUP BY owner) d

9   WHERE     a.owner = b.owner

10         AND a.object_id > b.object_id

11         AND b.CREATED > SYSDATE - 1

12         AND a.owner = d.owner;

no rows selected

Execution Plan

----------------------------------------------------------

Plan hash value: 3435586372

----------------------------------------------------------------------------------------------

| Id  | Operation                       | Name       | Rows  | Bytes | Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                |            |    42M|    16G|   104K  (1)| 00:20:56 |

|   1 |  NESTED LOOPS                   |            |    42M|    16G|   104K  (1)| 00:20:56 |

|*  2 |   HASH JOIN                     |            |  5771 |  2333K|   692   (1)| 00:00:09 |

|*  3 |    TABLE ACCESS FULL            | HTZ2       |    14 |  2898 |   346   (1)| 00:00:05 |

|   4 |    TABLE ACCESS FULL            | HTZ1       | 99677 |    19M|   345   (1)| 00:00:05 |

|   5 |   VIEW PUSHED PREDICATE         |            |     1 |    13 |    18   (0)| 00:00:01 |

|*  6 |    FILTER                       |            |       |       |            |          |

|   7 |     SORT AGGREGATE              |            |     1 |    30 |            |          |

|*  8 |      TABLE ACCESS BY INDEX ROWID| HTZ3       |   881 | 26430 |    18   (0)| 00:00:01 |

|*  9 |       INDEX RANGE SCAN          | IND_HTZ3_1 |   352 |       |     8   (0)| 00:00:01 |

----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("A"."OWNER"="B"."OWNER")

filter("A"."OBJECT_ID">"B"."OBJECT_ID")

3 - filter("B"."CREATED">SYSDATE@!-1)

6 - filter(COUNT(*)>0)

8 - filter("C"."OBJECT_ID">1000)

9 - access("OWNER"="A"."OWNER")

Note

-----

- dynamic sampling used for this statement (level=2)

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

2480  consistent gets

0  physical reads

0  redo size

2554  bytes sent via SQL*Net to client

512  bytes received via SQL*Net from client

1  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

0  rows processed

这里可以看到,逻辑读变,但是ORACLE的估算成本在这里下将了。

4.4 总结

上面结果是SQL不包括视图时执行还回的结果为0,几种方式的逻辑读基本没有发生变化。

5,语句二测试

下面这个SQL是有结果集还回的

SELECT *

FROM scott.htz1 a,

scott.htz2 b,

(  SELECT COUNT (*) COUNT, owner

FROM scott.htz3 c

WHERE c.object_id > 1000

GROUP BY owner) d

WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

可以看到还回了18行记录

5.1 默认情况

oracleplus.net> SELECT *

FROM scott.htz1 a,

scott.htz2 b,

(  SELECT COUNT (*) COUNT, owner

FROM scott.htz3 c

WHERE c.object_id > 1000

GROUP BY owner) d

WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

Elapsed: 00:00:00.05

Execution Plan

----------------------------------------------------------

Plan hash value: 1337491101

-------------------------------------------------------------------------------------

| Id  | Operation            | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT     |      |   847M|   350G|       |  5837  (40)| 00:01:11 |

|*  1 |  HASH JOIN           |      |   847M|   350G|  3616K|  5837  (40)| 00:01:11 |

|   2 |   VIEW               |      | 88109 |  2581K|       |   348   (2)| 00:00:05 |

|   3 |    HASH GROUP BY     |      | 88109 |  2581K|       |   348   (2)| 00:00:05 |

|*  4 |     TABLE ACCESS FULL| HTZ3 | 88109 |  2581K|       |   345   (1)| 00:00:05 |

|*  5 |   HASH JOIN          |      |   115K|    45M|       |   692   (1)| 00:00:09 |

|*  6 |    TABLE ACCESS FULL | HTZ2 |    14 |  2898 |       |   346   (1)| 00:00:05 |

|   7 |    TABLE ACCESS FULL | HTZ1 | 99677 |    19M|       |   345   (1)| 00:00:05 |

-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."OWNER"="D"."OWNER")

4 - filter("C"."OBJECT_ID">1000)

5 - access("A"."OWNER"="B"."OWNER")

6 - filter("B"."CREATED">SYSDATE@!-1)

Note

-----

- dynamic sampling used for this statement (level=2)

Statistics

----------------------------------------------------------

28  recursive calls

0  db block gets

4385  consistent gets

0  physical reads

0  redo size

4536  bytes sent via SQL*Net to client

534  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

7  sorts (memory)

0  sorts (disk)

18  rows processed

这里看到SQL的逻辑读是4385,TEMP消耗3616.

5.2 连接列创建索引

oracleplus.net>  create index scott.ind_htz3_1 on scott.htz3(owner);

Index created.

Elapsed: 00:00:00.08

oracleplus.net> SELECT *

2    FROM scott.htz1 a,

3         scott.htz2 b,

4         (  SELECT COUNT (*) COUNT, owner

5              FROM scott.htz3 c

6             WHERE c.object_id > 1000

7          GROUP BY owner) d

8   WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

Elapsed: 00:00:00.03

Execution Plan

----------------------------------------------------------

Plan hash value: 3445613030

------------------------------------------------------------------------------

| Id  | Operation             | Name | Rows  | Bytes | Cost (%CPU)| Time     |

------------------------------------------------------------------------------

|   0 | SELECT STATEMENT      |      |    19M|  4274M|  1095   (6)| 00:00:14 |

|*  1 |  HASH JOIN            |      |    19M|  4274M|  1095   (6)| 00:00:14 |

|*  2 |   TABLE ACCESS FULL   | HTZ2 |    80 |  7840 |   346   (1)| 00:00:05 |

|*  3 |   HASH JOIN           |      |   701K|    85M|   695   (2)| 00:00:09 |

|   4 |    VIEW               |      |    23 |   690 |   348   (2)| 00:00:05 |

|   5 |     HASH GROUP BY     |      |    23 |   253 |   348   (2)| 00:00:05 |

|*  6 |      TABLE ACCESS FULL| HTZ3 | 85470 |   918K|   345   (1)| 00:00:05 |

|   7 |    TABLE ACCESS FULL  | HTZ1 | 86448 |  8273K|   345   (1)| 00:00:05 |

------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."OWNER"="B"."OWNER")

2 - filter("B"."CREATED">SYSDATE@!-1)

3 - access("A"."OWNER"="D"."OWNER")

6 - filter("C"."OBJECT_ID">1000)

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

3719  consistent gets

0  physical reads

0  redo size

4536  bytes sent via SQL*Net to client

534  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

18  rows processed

这里看到逻辑读降到3719,COST也降到1095了。

5.3 强制谓词推入

oracleplus.net> SELECT /*+ push_pred(d)*/

2        *

3    FROM scott.htz1 a,

4         scott.htz2 b,

5         (  SELECT COUNT (*) COUNT, owner

6              FROM scott.htz3 c

7             WHERE c.object_id > 1000

8          GROUP BY owner) d

9   WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

FROM scott.htz1 a,

*

ERROR at line 3:

ORA-01013: user requested cancel of current operation

Elapsed: 00:05:19.68

运行很久没有结果

oracleplus.net> @sql_monitor_by_sqlid.sql

Enter value for sqlid: fkkvkv27pgqbx

SQL Monitoring Report

SQL Text

------------------------------

SELECT /*+ push_pred(d)*/ * FROM scott.htz1 a, scott.htz2 b, ( SELECT COUNT (*) COUNT, owner FROM scott.htz3 c WHERE c.object_id > 1000 GROUP BY owner) d WHERE a.owner = b.owner AND b.CREATED > SYSDAT

E - 1 AND a.owner = d.owner

Global Information

------------------------------

Status              :  EXECUTING

Instance ID         :  1

Session             :  SYS (26:7)

SQL ID              :  fkkvkv27pgqbx

SQL Execution ID    :  16777218

Execution Started   :  04/20/2015 22:06:30

First Refresh Time  :  04/20/2015 22:06:36

Last Refresh Time   :  04/20/2015 22:08:19

Duration            :  110s

Module/Action       :  sqlplus@orcl9i (TNS V1-V3)/-

Service             :  SYS$USERS

Program             :  sqlplus@orcl9i (TNS V1-V3)

Global Stats

===================================================================

| Elapsed |   Cpu   |    IO    |  Other   | Buffer | Read | Read  |

| Time(s) | Time(s) | Waits(s) | Waits(s) |  Gets  | Reqs | Bytes |

===================================================================

|     108 |     108 |     0.00 |     0.51 |    14M |    2 | 49152 |

===================================================================

SQL Plan Monitoring Details (Plan Hash Value=258155078)

======================================================================================================================================================================

| Id   |              Operation              |    Name    |  Rows   | Cost |   Time    | Start  | Execs |   Rows   | Read | Read  | Mem | Activity | Activity Detail |

|      |                                     |            | (Estim) |      | Active(s) | Active |       | (Actual) | Reqs | Bytes |     |   (%)    |   (# http://www.oracleplus.netsamples)   |

======================================================================================================================================================================

|    0 | SELECT STATEMENT                    |            |         |      |           |        |     1 |          |      |       |     |          |                 |

|    1 |   MERGE JOIN                        |            |     20M |  10M |           |        |     1 |          |      |       |     |          |                 |

| -> 2 |    SORT JOIN                        |            |    702K |  10M |       104 |     +6 |     1 |        0 |      |       |  2M |          |                 |

| -> 3 |     NESTED LOOPS                    |            |    702K |  10M |       104 |     +6 |     1 |    14028 |      |       |     |          |                 |

| -> 4 |      TABLE ACCESS FULL              | HTZ1       |   86448 |  345 |       104 |     +6 |     1 |    14028 |      |       |     |          |                 |

| -> 5 |      VIEW PUSHED PREDICATE          |            |       1 |  110 |       104 |     +6 | 14029 |    14028 |      |       |     |          |                 |

| -> 6 |       FILTER                        |            |         |      |       104 |     +6 | 14029 |    14028 |      |       |     |          |                 |

|    7 |        SORT AGGREGATE               |            |       1 |      |       104 |     +6 | 14029 |    14028 |      |       |     |     1.82 | Cpu (2)         |

|    8 |         TABLE ACCESS BY INDEX ROWID | HTZ3       |    3716 |  110 |       109 |     +1 | 14029 |     470M |      |       |     |    69.09 | Cpu (76)        |

| -> 9 |          INDEX RANGE SCAN           | IND_HTZ3_1 |    3759 |    9 |       105 |     +6 | 14029 |     480M |    2 | 49152 |     |    29.09 | Cpu (32)        |

|   10 |    SORT JOIN                        |            |      80 |  347 |           |        |       |          |      |       |     |          |                 |

|   11 |     TABLE ACCESS FULL               | HTZ2       |      80 |  346 |           |        |       |          |      |       |     |          |                 |

======================================================================================================================================================================

这里可以看到SQL的表间接顺序走错了,我们希望的是a,b做HASH,结果集与D走NL的方式

oracleplus.net> explain plan for

SELECT /*+ leading(a b d) SWAP_JOIN_INPUTS(a) no_swap_join_inputs(d) use_hash(a b d)  push_pred(d)*/

3        *

4    FROM scott.htz1 a,

5         scott.htz2 b,

6         (  SELECT COUNT (*) COUNT, owner

7              FROM scott.htz3 c

8             WHERE c.object_id > 1000

9          GROUP BY owner) d

10   WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

Explained.

Elapsed: 00:00:00.00

oracleplus.net> @plan_by_explain.sql

oracleplus.net> set lines 170

oracleplus.net> set pages 1000

oracleplus.net> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Plan hash value: 2320111649

------------------------------------------------------------------------------------------------------

| Id  | Operation                       | Name       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                |            |    19M|  3953M|       |   268M  (1)|896:07:11 |

|   1 |  NESTED LOOPS                   |            |    19M|  3953M|       |   268M  (1)|896:07:11 |

|*  2 |   HASH JOIN                     |            |  2442K|   456M|  9288K|  1149   (1)| 00:00:14 |

|   3 |    TABLE ACCESS FULL            | HTZ1       | 86448 |  8273K|       |   345   (1)| 00:00:05 |

|*  4 |    TABLE ACCESS FULL            | HTZ2       |    80 |  7840 |       |   346   (1)| 00:00:05 |

|   5 |   VIEW PUSHED PREDICATE         |            |     1 |    13 |       |   110   (0)| 00:00:02 |

|*  6 |    FILTER                       |            |       |       |       |            |          |

|   7 |     SORT AGGREGATE              |            |     1 |    11 |       |            |          |

|*  8 |      TABLE ACCESS BY INDEX ROWID| HTZ3       |  3716 | 40876 |       |   110   (0)| 00:00:02 |

|*  9 |       INDEX RANGE SCAN          | IND_HTZ3_1 |  3759 |       |       |     9   (0)| 00:00:01 |

------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("A"."OWNER"="B"."OWNER")

4 - filter("B"."CREATED">SYSDATE@!-1)

6 - filter(COUNT(*)>0)

8 - filter("C"."OBJECT_ID">1000)

9 - access("OWNER"="A"."OWNER")

25 rows selected.

Elapsed: 00:00:00.01

SELECT /*+ leading(a b d) SWAP_JOIN_INPUTS(a) no_swap_join_inputs(d) use_hash(a b d)  push_pred(d)*/

*

3    FROM scott.htz1 a,

4         scott.htz2 b,

5         (  SELECT COUNT (*) COUNT, owner

6              FROM scott.htz3 c

7             WHERE c.object_id > 1000

8          GROUP BY owner) d

9   WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

Elapsed: 00:00:00.05

Execution Plan

----------------------------------------------------------

Plan hash value: 2320111649

------------------------------------------------------------------------------------------------------

| Id  | Operation                       | Name       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT                |            |    19M|  3953M|       |   268M  (1)|896:07:11 |

|   1 |  NESTED LOOPS                   |            |    19M|  3953M|       |   268M  (1)|896:07:11 |

|*  2 |   HASH JOIN                     |            |  2442K|   456M|  9288K|  1149   (1)| 00:00:14 |

|   3 |    TABLE ACCESS FULL            | HTZ1       | 86448 |  8273K|       |   345   (1)| 00:00:05 |

|*  4 |    TABLE ACCESS FULL            | HTZ2       |    80 |  7840 |       |   346   (1)| 00:00:05 |

|   5 |   VIEW PUSHED PREDICATE         |            |     1 |    13 |       |   110   (0)| 00:00:02 |

|*  6 |    FILTER                       |            |       |       |       |            |          |

|   7 |     SORT AGGREGATE              |            |     1 |    11 |       |            |          |

|*  8 |      TABLE ACCESS BY INDEX ROWID| HTZ3       |  3716 | 40876 |       |   110   (0)| 00:00:02 |

|*  9 |       INDEX RANGE SCAN          | IND_HTZ3_1 |  3759 |       |       |     9   (0)| 00:00:01 |

------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("A"."OWNER"="B"."OWNER")

4 - filter("B"."CREATED">SYSDATE@!-1)

6 - filter(COUNT(*)>0)

8 - filter("C"."OBJECT_ID">1000)

9 - access("OWNER"="A"."OWNER")

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

2543  consistent gets

0  physical reads

0  redo size

4047  bytes sent via SQL*Net to client

534  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

18  rows processed

这里看到逻辑读下降到2543,但是消耗了temspc空间,cost也是很多的。

其实VIEW中条件越多,创建组合索引效果会更好

oracleplus.net> create index scott.ind_htz3_2 on scott.htz3(owner,object_id);

Index created.

Elapsed: 00:00:00.10

SELECT /*+ leading(a b d) SWAP_JOIN_INPUTS(a) no_swap_join_inputs(d) use_hash(a b d)  push_pred(d)*/

2        *

3    FROM scott.htz1 a,

4         scott.htz2 b,

5         (  SELECT COUNT (*) COUNT, owner

6              FROM scott.htz3 c

7             WHERE c.object_id > 1000

8          GROUP BY owner) d

9   WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

Elapsed: 00:00:00.04

Execution Plan

----------------------------------------------------------

Plan hash value: 1875749008

----------------------------------------------------------------------------------------------

| Id  | Operation               | Name       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT        |            |    19M|  3953M|       |    29M  (1)| 97:53:05 |

|   1 |  NESTED LOOPS           |            |    19M|  3953M|       |    29M  (1)| 97:53:05 |

|*  2 |   HASH JOIN             |            |  2442K|   456M|  9288K|  1149   (1)| 00:00:14 |

|   3 |    TABLE ACCESS FULL    | HTZ1       | 86448 |  8273K|       |   345   (1)| 00:00:05 |

|*  4 |    TABLE ACCESS FULL    | HTZ2       |    80 |  7840 |       |   346   (1)| 00:00:05 |

|   5 |   VIEW PUSHED PREDICATE |            |     1 |    13 |       |    12   (0)| 00:00:01 |

|*  6 |    FILTER               |            |       |       |       |            |          |

|   7 |     SORT AGGREGATE      |            |     1 |    11 |       |            |          |

|*  8 |      INDEX RANGE SCAN   | IND_HTZ3_2 |  3716 | 40876 |       |    12   (0)| 00:00:01 |

----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

2 - access("A"."OWNER"="B"."OWNER")

4 - filter("B"."CREATED">SYSDATE@!-1)

6 - filter(COUNT(*)>0)

8 - access("OWNER"="A"."OWNER" AND "C"."OBJECT_ID">1000 AND "C"."OBJECT_ID" IS NOT

NULL)

Statistics

----------------------------------------------------------

0  recursive calls

0  db block gets

2489  consistent gets  这里减少了54个BLOCK基本就是一下回表的操作

0  physical reads

0  redo size

4047  bytes sent via SQL*Net to client

534  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

18  rows processed

6,禁用推入

oracleplus.net> alter system set "_optimizer_extend_jppd_view_types"=false;

System altered.

Elapsed: 00:00:00.01

禁用_optimizer_extend_jppd_view_types参数,这里可以看到走HASH,消耗大量TEMPSPC

SELECT /*+ leading(a b d) SWAP_JOIN_INPUTS(a) no_swap_join_inputs(d) use_hash(a b d)  push_pred(d)*/

*

3        FROM scott.htz1 a,

4             scott.htz2 b,

5             (  SELECT COUNT (*) COUNT, owner

6                  FROM scott.htz3 c

7                 WHERE c.object_id > 1000

8              GROUP BY owner) d

9       WHERE a.owner = b.owner AND b.CREATED > SYSDATE - 1 AND a.owner = d.owner;

18 rows selected.

Elapsed: 00:00:00.06

Execution Plan

----------------------------------------------------------

Plan hash value: 2571011931

----------------------------------------------------------------------------------------------

| Id  | Operation               | Name       | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |

----------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT        |            |    19M|  4274M|       | 25302   (1)| 00:05:04 |

|*  1 |  HASH JOIN              |            |    19M|  4274M|   484M| 25302   (1)| 00:05:04 |

|*  2 |   HASH JOIN             |            |  2442K|   456M|  9288K|  1149   (1)| 00:00:14 |

|   3 |    TABLE ACCESS FULL    | HTZ1       | 86448 |  8273K|       |   345   (1)| 00:00:05 |

|*  4 |    TABLE ACCESS FULL    | HTZ2       |    80 |  7840 |       |   346   (1)| 00:00:05 |

|   5 |   VIEW                  |            |    23 |   690 |       |    75   (4)| 00:00:01 |

|   6 |    HASH GROUP BY        |            |    23 |   253 |       |    75   (4)| 00:00:01 |

|*  7 |     INDEX FAST FULL SCAN| IND_HTZ3_2 | 85470 |   918K|       |    72   (0)| 00:00:01 |

----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

1 - access("A"."OWNER"="D"."OWNER")

2 - access("A"."OWNER"="B"."OWNER")

4 - filter("B"."CREATED">SYSDATE@!-1)

7 - filter("C"."OBJECT_ID">1000)

Statistics

----------------------------------------------------------

1  recursive calls

0  db block gets

2746  consistent gets

0  physical reads

0  redo size

4080  bytes sent via SQL*Net to client

534  bytes received via SQL*Net from client

3  SQL*Net roundtrips to/from client

0  sorts (memory)

0  sorts (disk)

18  rows processed

测试结束

MOS中已经有很多文档对连接列谓词推入做了详细说明

本文固定链接: http://www.htz.pw/2015/04/21/optimizer-join-push-predicate.html | 认真就输

--------------------------------------ORACLE-DBA----------------------------------------

最权威、专业的Oracle案例资源汇总之【案例】Oracle优化之优化SQL时遇到连接谓词推入不成功分析

9bd101509341196819122f36086c9a60.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值