Quantcast
Channel: love wife & love life —Roger 的Oracle技术博客 » tunning
Viewing all articles
Browse latest Browse all 12

_optimizer_null_aware_antijoin引发的SQL性能问题

$
0
0

本站文章除注明转载外,均为本站原创: 转载自love wife & love life —Roger 的Oracle技术博客

本文链接地址: _optimizer_null_aware_antijoin引发的SQL性能问题

前几天某客户联系我说之前我们进行存储迁移的系统,有个SQL跑的极慢,根本跑不出来结果。通过VPN登录看了下,SQL确认跑的很慢。开始我很难理解,我们仅仅是进行了存储迁移,数据库基本上没动,为什么会有SQL性能问题呢?  我们先来看看有问题的SQL:

SYS@rptdb1> set autot traceonly exp
SYS@rptdb1> select a.*,b.rate TAX_RATE,round(a.charge*b.rate/(1+b.rate),0) tax,a.charge-round((a.charge*b.rate/(1+b.rate)),0) charge_flh,1 flag,b.tax_rule_id
  2               from statrpt.rpt_offer_rate b,statrpt.tmp_item_aggr_ex_691  a
  3               where  a.acct_item_type_id = b.acct_item_type_id
  4               and a.offer_cd =b.offer_ID
  5             union all
  6
SYS@rptdb1>              select a.*,b.rate TAX_RATE,round(a.charge*b.rate/(1+b.rate),0) tax,a.charge-ROUND((a.charge*b.rate/(1+b.rate)),0) charge_flh,2,b.tax_rule_id
  2               from  statrpt.rpt_product_rate b,statrpt.tmp_item_aggr_ex_691  a
  3               where   a.acct_item_type_id = b.acct_item_type_id
  4               and  a.product_id=b.product_id
  5               and (a.acct_item_type_id,a.offer_cd) not in(select acct_item_type_id,offer_id from statrpt.rpt_offer_rate)
  6              union all
  7
SYS@rptdb1>              select a.*,b.rate TAX_RATE,round(a.charge*b.rate/(1+b.rate),0) tax,a.charge-round((a.charge*b.rate/(1+b.rate)),0) charge_flh,3,b.tax_rule_id
  2               from  statrpt.rpt_zm_rate b,statrpt.tmp_item_aggr_ex_691  a
  3               where  a.acct_item_type_id = b.acct_item_type_id
  4               and (a.acct_item_type_id,a.offer_cd)not in(select acct_item_type_id,offer_id from statrpt.rpt_offer_rate )
  5               and (a.acct_item_type_id,a.product_id) not in(select acct_item_type_id,product_id from statrpt.rpt_product_rate )
  6               union all
  7               select a.*,b.rate TAX_RATE,round(a.charge*b.rate/(1+b.rate),0) tax,a.charge-round((a.charge*b.rate/(1+b.rate)),0) charge_flh,4,b.tax_rule_id
  8               from  statrpt.tmp_zm_only_rate b,statrpt.tmp_item_aggr_ex_691  a
  9               where  a.acct_item_type_id = b.acct_item_type_id
 10               and (a.acct_item_type_id,a.offer_cd)not in(select acct_item_type_id,offer_id from statrpt.rpt_offer_rate )
 11               and (a.acct_item_type_id,a.product_id) not in(select acct_item_type_id,product_id from statrpt.rpt_product_rate )
 12               and (a.acct_item_type_id) not in(select acct_item_type_id from statrpt.rpt_zm_rate )
 13  /
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
Plan hash value: 1624413711

-------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                 | Name                 | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT          |                      |  6983K|   765M|   563M (51)|999:59:59 |        |      |            |
|   1 |  UNION-ALL                |                      |       |       |            |          |        |      |            |
|*  2 |   FILTER                  |                      |       |       |            |          |        |      |            |
|   3 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|   4 |     PX SEND QC (RANDOM)   | :TQ60001             |  3494K|   383M|  1050   (1)| 00:00:13 |  Q6,01 | P->S | QC (RAND)  |
|*  5 |      HASH JOIN            |                      |  3494K|   383M|  1050   (1)| 00:00:13 |  Q6,01 | PCWP |            |
|   6 |       PX RECEIVE          |                      |  1034 | 14476 |     3   (0)| 00:00:01 |  Q6,01 | PCWP |            |
|   7 |        PX SEND BROADCAST  | :TQ60000             |  1034 | 14476 |     3   (0)| 00:00:01 |  Q6,00 | P->P | BROADCAST  |
|   8 |         PX BLOCK ITERATOR |                      |  1034 | 14476 |     3   (0)| 00:00:01 |  Q6,00 | PCWC |            |
|   9 |          TABLE ACCESS FULL| RPT_ZM_RATE          |  1034 | 14476 |     3   (0)| 00:00:01 |  Q6,00 | PCWP |            |
|  10 |       PX BLOCK ITERATOR   |                      |  3494K|   336M|  1046   (1)| 00:00:13 |  Q6,01 | PCWC |            |
|  11 |        TABLE ACCESS FULL  | TMP_ITEM_AGGR_EX_691 |  3494K|   336M|  1046   (1)| 00:00:13 |  Q6,01 | PCWP |            |
|  12 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  13 |     PX SEND QC (RANDOM)   | :TQ10000             |     1 |     9 |     8   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|  14 |      PX BLOCK ITERATOR    |                      |     1 |     9 |     8   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|* 15 |       TABLE ACCESS FULL   | RPT_OFFER_RATE       |     1 |     9 |     8   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|  16 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  17 |     PX SEND QC (RANDOM)   | :TQ20000             |     1 |     9 |    96   (2)| 00:00:02 |  Q2,00 | P->S | QC (RAND)  |
|  18 |      PX BLOCK ITERATOR    |                      |     1 |     9 |    96   (2)| 00:00:02 |  Q2,00 | PCWC |            |
|* 19 |       TABLE ACCESS FULL   | RPT_PRODUCT_RATE     |     1 |     9 |    96   (2)| 00:00:02 |  Q2,00 | PCWP |            |
|* 20 |   FILTER                  |                      |       |       |            |          |        |      |            |
|  21 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  22 |     PX SEND QC (RANDOM)   | :TQ70001             |  3494K|   383M|  1050   (1)| 00:00:13 |  Q7,01 | P->S | QC (RAND)  |
|* 23 |      HASH JOIN            |                      |  3494K|   383M|  1050   (1)| 00:00:13 |  Q7,01 | PCWP |            |
|  24 |       PX RECEIVE          |                      |  6053 | 84742 |     3   (0)| 00:00:01 |  Q7,01 | PCWP |            |
|  25 |        PX SEND BROADCAST  | :TQ70000             |  6053 | 84742 |     3   (0)| 00:00:01 |  Q7,00 | P->P | BROADCAST  |
|  26 |         PX BLOCK ITERATOR |                      |  6053 | 84742 |     3   (0)| 00:00:01 |  Q7,00 | PCWC |            |
|  27 |          TABLE ACCESS FULL| TMP_ZM_ONLY_RATE     |  6053 | 84742 |     3   (0)| 00:00:01 |  Q7,00 | PCWP |            |
|  28 |       PX BLOCK ITERATOR   |                      |  3494K|   336M|  1046   (1)| 00:00:13 |  Q7,01 | PCWC |            |
|  29 |        TABLE ACCESS FULL  | TMP_ITEM_AGGR_EX_691 |  3494K|   336M|  1046   (1)| 00:00:13 |  Q7,01 | PCWP |            |
|  30 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  31 |     PX SEND QC (RANDOM)   | :TQ30000             |     1 |     9 |     8   (0)| 00:00:01 |  Q3,00 | P->S | QC (RAND)  |
|  32 |      PX BLOCK ITERATOR    |                      |     1 |     9 |     8   (0)| 00:00:01 |  Q3,00 | PCWC |            |
|* 33 |       TABLE ACCESS FULL   | RPT_OFFER_RATE       |     1 |     9 |     8   (0)| 00:00:01 |  Q3,00 | PCWP |            |
|  34 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  35 |     PX SEND QC (RANDOM)   | :TQ40000             |     1 |     9 |    96   (2)| 00:00:02 |  Q4,00 | P->S | QC (RAND)  |
|  36 |      PX BLOCK ITERATOR    |                      |     1 |     9 |    96   (2)| 00:00:02 |  Q4,00 | PCWC |            |
|* 37 |       TABLE ACCESS FULL   | RPT_PRODUCT_RATE     |     1 |     9 |    96   (2)| 00:00:02 |  Q4,00 | PCWP |            |
|  38 |    PX COORDINATOR         |                      |       |       |            |          |        |      |            |
|  39 |     PX SEND QC (RANDOM)   | :TQ50000             |     1 |     5 |     3   (0)| 00:00:01 |  Q5,00 | P->S | QC (RAND)  |
|  40 |      PX BLOCK ITERATOR    |                      |     1 |     5 |     3   (0)| 00:00:01 |  Q5,00 | PCWC |            |
|* 41 |       TABLE ACCESS FULL   | RPT_ZM_RATE          |     1 |     5 |     3   (0)| 00:00:01 |  Q5,00 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter( NOT EXISTS (SELECT 0 FROM "STATRPT"."RPT_OFFER_RATE" "RPT_OFFER_RATE" WHERE
              LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("OFFER_ID"<>:B2)) AND  NOT EXISTS (SELECT 0 FROM
              "STATRPT"."RPT_PRODUCT_RATE" "RPT_PRODUCT_RATE" WHERE LNNVL("ACCT_ITEM_TYPE_ID"<>:B3) AND LNNVL("PRODUCT_ID"<>:B4)))
   5 - access("A"."ACCT_ITEM_TYPE_ID"="B"."ACCT_ITEM_TYPE_ID")
  15 - filter(LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("OFFER_ID"<>:B2))
  19 - filter(LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("PRODUCT_ID"<>:B2))
  20 - filter( NOT EXISTS (SELECT 0 FROM "STATRPT"."RPT_OFFER_RATE" "RPT_OFFER_RATE" WHERE
              LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("OFFER_ID"<>:B2)) AND  NOT EXISTS (SELECT 0 FROM
              "STATRPT"."RPT_PRODUCT_RATE" "RPT_PRODUCT_RATE" WHERE LNNVL("ACCT_ITEM_TYPE_ID"<>:B3) AND LNNVL("PRODUCT_ID"<>:B4))
              AND  NOT EXISTS (SELECT 0 FROM "STATRPT"."RPT_ZM_RATE" "RPT_ZM_RATE" WHERE LNNVL("ACCT_ITEM_TYPE_ID"<>:B5)))
  23 - access("A"."ACCT_ITEM_TYPE_ID"="B"."ACCT_ITEM_TYPE_ID")
  33 - filter(LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("OFFER_ID"<>:B2))
  37 - filter(LNNVL("ACCT_ITEM_TYPE_ID"<>:B1) AND LNNVL("PRODUCT_ID"<>:B2))
  41 - filter(LNNVL("ACCT_ITEM_TYPE_ID"<>:B1))

 

 

大家看该SQL的执行计划就知道,COST巨大无比,很显然这个SQL基本上是跑不动的。本人SQL优化比较弱,因此直接从原库进行对比,因此在原库跑了下SQL:

Plan hash value: 2514835211

---------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name                 | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                      |       |       |       |  3493 (100)|          |        |      |            |
|   1 |  UNION-ALL                      |                      |       |       |       |            |          |        |      |            |
|   2 |   PX COORDINATOR                |                      |       |       |       |            |          |        |      |            |
|   3 |    PX SEND QC (RANDOM)          | :TQ10004             |   557 | 71853 |       |  1745   (3)| 00:00:21 |  Q1,04 | P->S | QC (RAND)  |
|*  4 |     HASH JOIN BUFFERED          |                      |   557 | 71853 |       |  1745   (3)| 00:00:21 |  Q1,04 | PCWP |            |
|   5 |      PX RECEIVE                 |                      |   557 | 64055 |       |  1742   (3)| 00:00:21 |  Q1,04 | PCWP |            |
|   6 |       PX SEND HASH              | :TQ10002             |   557 | 64055 |       |  1742   (3)| 00:00:21 |  Q1,02 | P->P | HASH       |
|   7 |        MERGE JOIN ANTI NA       |                      |   557 | 64055 |       |  1742   (3)| 00:00:21 |  Q1,02 | PCWP |            |
|   8 |         SORT JOIN               |                      | 55738 |  5769K|    12M|  1733   (3)| 00:00:21 |  Q1,02 | PCWP |            |
|   9 |          MERGE JOIN ANTI NA     |                      | 55738 |  5769K|       |  1732   (3)| 00:00:21 |  Q1,02 | PCWP |            |
|  10 |           SORT JOIN             |                      |  5573K|   515M|  1643M|  1631   (2)| 00:00:20 |  Q1,02 | PCWP |            |
|  11 |            PX BLOCK ITERATOR    |                      |  5573K|   515M|       |  1614   (1)| 00:00:20 |  Q1,02 | PCWC |            |
|* 12 |             TABLE ACCESS FULL   | TMP_ITEM_AGGR_EX_691 |  5573K|   515M|       |  1614   (1)| 00:00:20 |  Q1,02 | PCWP |            |
|* 13 |           SORT UNIQUE           |                      |   421K|  3704K|    16M|   101   (5)| 00:00:02 |  Q1,02 | PCWP |            |
|  14 |            PX RECEIVE           |                      |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q1,02 | PCWP |            |
|  15 |             PX SEND BROADCAST   | :TQ10000             |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q1,00 | P->P | BROADCAST  |
|  16 |              PX BLOCK ITERATOR  |                      |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q1,00 | PCWC |            |
|* 17 |               TABLE ACCESS FULL | RPT_PRODUCT_RATE     |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q1,00 | PCWP |            |
|* 18 |         SORT UNIQUE             |                      | 22695 |   199K|       |     9  (12)| 00:00:01 |  Q1,02 | PCWP |            |
|  19 |          PX RECEIVE             |                      | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q1,02 | PCWP |            |
|  20 |           PX SEND BROADCAST     | :TQ10001             | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q1,01 | P->P | BROADCAST  |
|  21 |            PX BLOCK ITERATOR    |                      | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q1,01 | PCWC |            |
|* 22 |             TABLE ACCESS FULL   | RPT_OFFER_RATE       | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q1,01 | PCWP |            |
|  23 |      PX RECEIVE                 |                      |  1059 | 14826 |       |     3   (0)| 00:00:01 |  Q1,04 | PCWP |            |
|  24 |       PX SEND HASH              | :TQ10003             |  1059 | 14826 |       |     3   (0)| 00:00:01 |  Q1,03 | P->P | HASH       |
|  25 |        PX BLOCK ITERATOR        |                      |  1059 | 14826 |       |     3   (0)| 00:00:01 |  Q1,03 | PCWC |            |
|* 26 |         TABLE ACCESS FULL       | RPT_ZM_RATE          |  1059 | 14826 |       |     3   (0)| 00:00:01 |  Q1,03 | PCWP |            |
|  27 |   PX COORDINATOR                |                      |       |       |       |            |          |        |      |            |
|  28 |    PX SEND QC (RANDOM)          | :TQ20004             |     6 |   804 |       |  1748   (3)| 00:00:21 |  Q2,04 | P->S | QC (RAND)  |
|* 29 |     HASH JOIN                   |                      |     6 |   804 |       |  1748   (3)| 00:00:21 |  Q2,04 | PCWP |            |
|  30 |      PX RECEIVE                 |                      |     6 |   720 |       |  1745   (3)| 00:00:21 |  Q2,04 | PCWP |            |
|  31 |       PX SEND BROADCAST         | :TQ20003             |     6 |   720 |       |  1745   (3)| 00:00:21 |  Q2,03 | P->P | BROADCAST  |
|  32 |        MERGE JOIN ANTI NA       |                      |     6 |   720 |       |  1745   (3)| 00:00:21 |  Q2,03 | PCWP |            |
|  33 |         SORT JOIN               |                      |   557 | 61827 |       |  1736   (3)| 00:00:21 |  Q2,03 | PCWP |            |
|* 34 |          HASH JOIN RIGHT ANTI NA|                      |   557 | 61827 |       |  1735   (3)| 00:00:21 |  Q2,03 | PCWP |            |
|  35 |           PX RECEIVE            |                      |  1059 |  5295 |       |     3   (0)| 00:00:01 |  Q2,03 | PCWP |            |
|  36 |            PX SEND BROADCAST    | :TQ20000             |  1059 |  5295 |       |     3   (0)| 00:00:01 |  Q2,00 | P->P | BROADCAST  |
|  37 |             PX BLOCK ITERATOR   |                      |  1059 |  5295 |       |     3   (0)| 00:00:01 |  Q2,00 | PCWC |            |
|* 38 |              TABLE ACCESS FULL  | RPT_ZM_RATE          |  1059 |  5295 |       |     3   (0)| 00:00:01 |  Q2,00 | PCWP |            |
|  39 |           MERGE JOIN ANTI NA    |                      | 55738 |  5769K|       |  1732   (3)| 00:00:21 |  Q2,03 | PCWP |            |
|  40 |            SORT JOIN            |                      |  5573K|   515M|  1643M|  1631   (2)| 00:00:20 |  Q2,03 | PCWP |            |
|  41 |             PX BLOCK ITERATOR   |                      |  5573K|   515M|       |  1614   (1)| 00:00:20 |  Q2,03 | PCWC |            |
|* 42 |              TABLE ACCESS FULL  | TMP_ITEM_AGGR_EX_691 |  5573K|   515M|       |  1614   (1)| 00:00:20 |  Q2,03 | PCWP |            |
|* 43 |            SORT UNIQUE          |                      |   421K|  3704K|    16M|   101   (5)| 00:00:02 |  Q2,03 | PCWP |            |
|  44 |             PX RECEIVE          |                      |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q2,03 | PCWP |            |
|  45 |              PX SEND BROADCAST  | :TQ20001             |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q2,01 | P->P | BROADCAST  |
|  46 |               PX BLOCK ITERATOR |                      |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q2,01 | PCWC |            |
|* 47 |                TABLE ACCESS FULL| RPT_PRODUCT_RATE     |   421K|  3704K|       |    96   (0)| 00:00:02 |  Q2,01 | PCWP |            |
|* 48 |         SORT UNIQUE             |                      | 22695 |   199K|       |     9  (12)| 00:00:01 |  Q2,03 | PCWP |            |
|  49 |          PX RECEIVE             |                      | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q2,03 | PCWP |            |
|  50 |           PX SEND BROADCAST     | :TQ20002             | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q2,02 | P->P | BROADCAST  |
|  51 |            PX BLOCK ITERATOR    |                      | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q2,02 | PCWC |            |
|* 52 |             TABLE ACCESS FULL   | RPT_OFFER_RATE       | 22695 |   199K|       |     8   (0)| 00:00:01 |  Q2,02 | PCWP |            |
|  53 |      PX BLOCK ITERATOR          |                      |  6083 | 85162 |       |     3   (0)| 00:00:01 |  Q2,04 | PCWC |            |
|* 54 |       TABLE ACCESS FULL         | TMP_ZM_ONLY_RATE     |  6083 | 85162 |       |     3   (0)| 00:00:01 |  Q2,04 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("A"."ACCT_ITEM_TYPE_ID"="B"."ACCT_ITEM_TYPE_ID")
  12 - access(:Z>=:Z AND :Z<=:Z)
  13 - access(INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID") AND
              INTERNAL_FUNCTION("A"."PRODUCT_ID")=INTERNAL_FUNCTION("PRODUCT_ID"))
       filter((INTERNAL_FUNCTION("A"."PRODUCT_ID")=INTERNAL_FUNCTION("PRODUCT_ID") AND
              INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID")))
  17 - access(:Z>=:Z AND :Z<=:Z)
  18 - access(INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID") AND
              INTERNAL_FUNCTION("A"."OFFER_CD")=INTERNAL_FUNCTION("OFFER_ID"))
       filter((INTERNAL_FUNCTION("A"."OFFER_CD")=INTERNAL_FUNCTION("OFFER_ID") AND
              INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID")))
  22 - access(:Z>=:Z AND :Z<=:Z)
  26 - access(:Z>=:Z AND :Z<=:Z)
  29 - access("A"."ACCT_ITEM_TYPE_ID"="B"."ACCT_ITEM_TYPE_ID")
  34 - access("A"."ACCT_ITEM_TYPE_ID"="ACCT_ITEM_TYPE_ID")
  38 - access(:Z>=:Z AND :Z<=:Z)
  42 - access(:Z>=:Z AND :Z<=:Z)
  43 - access(INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID") AND
              INTERNAL_FUNCTION("A"."PRODUCT_ID")=INTERNAL_FUNCTION("PRODUCT_ID"))
       filter((INTERNAL_FUNCTION("A"."PRODUCT_ID")=INTERNAL_FUNCTION("PRODUCT_ID") AND
              INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID")))
  47 - access(:Z>=:Z AND :Z<=:Z)
  48 - access(INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID") AND
              INTERNAL_FUNCTION("A"."OFFER_CD")=INTERNAL_FUNCTION("OFFER_ID"))
       filter((INTERNAL_FUNCTION("A"."OFFER_CD")=INTERNAL_FUNCTION("OFFER_ID") AND
              INTERNAL_FUNCTION("A"."ACCT_ITEM_TYPE_ID")=INTERNAL_FUNCTION("ACCT_ITEM_TYPE_ID")))
  52 - access(:Z>=:Z AND :Z<=:Z)
  54 - access(:Z>=:Z AND :Z<=:Z)

 

 

很明显,原库的执行计划要好的,通过对比执行计划,我们发现:性能较差的SQL的执行计划中,not in 被改写成了not exits,进行了一些filter操作。而性能较高的SQL的执行计划,则是选择了ANTI Join。
问题是原来为什么ok ?存储迁移之后就有问题了呢 ?第一感觉可能是调整了优化器参数,检查发现果然是:

SYS@rptdb1> show parameter optimizer

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
_optimizer_adaptive_cursor_sharing   boolean     FALSE
_optimizer_extended_cursor_sharing   string      NONE
_optimizer_extended_cursor_sharing_r string      NONE
el
_optimizer_null_aware_antijoin       boolean     FALSE
_optimizer_use_feedback              boolean     FALSE
optimizer_capture_sql_plan_baselines boolean     FALSE
optimizer_dynamic_sampling           integer     2
optimizer_features_enable            string      11.2.0.2
optimizer_index_caching              integer     0
optimizer_index_cost_adj             integer     100
optimizer_mode                       string      ALL_ROWS
optimizer_secure_view_merging        boolean     TRUE
optimizer_use_invisible_indexes      boolean     FALSE
optimizer_use_pending_statistics     boolean     FALSE
optimizer_use_sql_plan_baselines     boolean     TRUE
SYS@rptdb1>
SYS@rptdb1> alter session set "_optimizer_null_aware_antijoin"=true;

Session altered.

通过将该参数改回默认值,测试一切正常。 这里我主要是通过SQLT来解决该SQL的性能问题,首先创建一个SQL profile,然后修改SQL profile的查询块信息即可,如下:

q'[OPT_PARAM('_optimizer_null_aware_antijoin' 'true')]',
q'[OPT_PARAM('_optimizer_extended_cursor_sharing' 'none')]',
q'[OPT_PARAM('_optimizer_extended_cursor_sharing_rel' 'none')]',
q'[OPT_PARAM('_optimizer_adaptive_cursor_sharing' 'false')]',
q'[OPT_PARAM('_optimizer_use_feedback' 'false')]',

通过调整之后,SQL性能恢复正常。 虽然这是一个很常见的问题,然而我却是第一次在生产中碰见,下面进行一个简单的测试。
说明:测试脚本来自google。
—For 10.2.0.5

www.killdb.com> create table t1
  2  as select
  3  cast(rownum as int) a,
  4  cast(rownum+10 as int) b,
  5  cast(dbms_random.string('i',10) as varchar2(10)) c
  6  from dual connect by level<=10000;

Table created.

www.killdb.com> create table t2
  2  as select
  3  cast(rownum as int) a,
  4  cast(rownum+10 as int) b,
  5  cast(dbms_random.string('i',10) as varchar2(10)) c
  6  from dual connect by level<=9980;

Table created.

www.killdb.com>
www.killdb.com> set autot traceonly exp
www.killdb.com> analyze table t1 compute statistics;

Table analyzed.

www.killdb.com> analyze table t2 compute statistics;

Table analyzed.

www.killdb.com> select /*SQL_1*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 895956251

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  9999 |   126K| 60407   (1)| 00:12:05 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| T1   | 10000 |   126K|    12   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     1 |     3 |    12   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( NOT EXISTS (SELECT 0 FROM "T2" "T2" WHERE
              LNNVL("A"<>:B1)))
   3 - filter(LNNVL("A"<>:B1))

www.killdb.com> alter table t2 modify a not null ;

Table altered.

www.killdb.com> select /*SQL_2*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 895956251

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  9999 |   126K| 60407   (1)| 00:12:05 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| T1   | 10000 |   126K|    12   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     1 |     3 |    12   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( NOT EXISTS (SELECT 0 FROM "T2" "T2" WHERE
              LNNVL("A"<>:B1)))
   3 - filter(LNNVL("A"<>:B1))

www.killdb.com> create index idx_t2_a on t2(a);

Index created.

www.killdb.com> create index idx_t1_a on t1(a);

Index created.

www.killdb.com> select /*SQL_3*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 377637984

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |  9999 |   126K| 35333   (1)| 00:07:04 |
|*  1 |  FILTER               |          |       |       |            |          |
|   2 |   TABLE ACCESS FULL   | T1       | 10000 |   126K|    12   (0)| 00:00:01 |
|*  3 |   INDEX FAST FULL SCAN| IDX_T2_A |     1 |     3 |     7   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( NOT EXISTS (SELECT 0 FROM "T2" "T2" WHERE LNNVL("A"<>:B1)))
   3 - filter(LNNVL("A"<>:B1))

www.killdb.com>

我们可以看到,仍然没有走办连接,还是走filter了,这里的类似nest loop,很明显效率很低,其原因是需要用T1表的每条记录去和T2 返回的结果集进行匹配。那么有没有办法让SQL走半连接呢 ? 肯定是可以的,如下:

www.killdb.com> alter table t1 modify a not null ;

Table altered.

www.killdb.com> select /*SQL_4*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 1490751970

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |    20 |   320 |    20   (5)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT ANTI |          |    20 |   320 |    20   (5)| 00:00:01 |
|   2 |   INDEX FAST FULL SCAN| IDX_T2_A |  9980 | 29940 |     7   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL   | T1       | 10000 |   126K|    12   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"="A")

我们可以看到,走半连接之后,效率明显要高的多。当然,这里不对t1表进行not null操作也可以进行优化。
—-for 11.2.0.2 test

[ora11g@localhost ~]$ sqlplus "/as sysdba"

SQL*Plus: Release 11.2.0.2.0 Production on Sat Apr 18 22:59:32 2015

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
With the Partitioning, Automatic Storage Management, OLAP, Data Mining
and Real Application Testing options

www.killdb.com> conn roger/roger
Connected.
www.killdb.com>

SQL> create table t1
  2  as select
  3  cast(rownum as int) a,
  4  cast(rownum+10 as int) b,
  5  cast(dbms_random.string('i',10) as varchar2(10)) c
  6  from dual connect by level<=10000;

Table created.

SQL> create table t2
  2  as select
  3  cast(rownum as int) a,
  4  cast(rownum+10 as int) b,
  5  cast(dbms_random.string('i',10) as varchar2(10)) c
  6  from dual connect by level<=9980;

Table created.

SQL> analyze table t1 compute statistics ;

Table analyzed.

SQL> analyze table t2 compute statistics;

Table analyzed.

SQL> set autot traceonly exp
SQL> select /*SQL_1*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 2739594415

--------------------------------------------------------------------------------
| Id  | Operation               | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |      |   100 |  1600 |    23   (5)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT ANTI NA|      |   100 |  1600 |    23   (5)| 00:00:01 |
|   2 |   TABLE ACCESS FULL     | T2   |  9980 | 29940 |    11   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL     | T1   | 10000 |   126K|    11   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"="A")

SQL> alter session set "_optimizer_null_aware_antijoin"=false;

Session altered.

SQL> select /*SQL_2*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 895956251

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |  9999 |   126K| 55478   (1)| 00:11:06 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| T1   | 10000 |   126K|    11   (0)| 00:00:01 |
|*  3 |   TABLE ACCESS FULL| T2   |     1 |     3 |    11   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( NOT EXISTS (SELECT 0 FROM "T2" "T2" WHERE
              LNNVL("A"<>:B1)))
   3 - filter(LNNVL("A"<>:B1))

SQL> alter table t2 modify a not null;

Table altered.

SQL> create index idx_t2_a on t2(a);

Index created.

SQL> create index idx_t1_a on t1(a);

Index created.

SQL>
SQL> alter session set "_optimizer_null_aware_antijoin"=true;

Session altered.

SQL>  select /*SQL_3*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 2568882110

-------------------------------------------------------------------------------------
| Id  | Operation                | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |          |   100 |  1600 |    19   (6)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT ANTI SNA|          |   100 |  1600 |    19   (6)| 00:00:01 |
|   2 |   INDEX FAST FULL SCAN   | IDX_T2_A |  9980 | 29940 |     7   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL      | T1       | 10000 |   126K|    11   (0)| 00:00:01 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"="A")

SQL> alter session set "_optimizer_null_aware_antijoin"=false;

Session altered.

SQL> select /*SQL_3*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 377637984

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |  9999 |   126K| 35396   (2)| 00:07:05 |
|*  1 |  FILTER               |          |       |       |            |          |
|   2 |   TABLE ACCESS FULL   | T1       | 10000 |   126K|    11   (0)| 00:00:01 |
|*  3 |   INDEX FAST FULL SCAN| IDX_T2_A |     1 |     3 |     7   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter( NOT EXISTS (SELECT 0 FROM "T2" "T2" WHERE LNNVL("A"<>:B1)))
   3 - filter(LNNVL("A"<>:B1))

SQL>  alter table t1 modify a not null ;

Table altered.

SQL> select /*SQL_3*/ c from t1 where a not in (select a from t2) ;

Execution Plan
----------------------------------------------------------
Plan hash value: 1490751970

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |   100 |  1600 |    19   (6)| 00:00:01 |
|*  1 |  HASH JOIN RIGHT ANTI |          |   100 |  1600 |    19   (6)| 00:00:01 |
|   2 |   INDEX FAST FULL SCAN| IDX_T2_A |  9980 | 29940 |     7   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL   | T1       | 10000 |   126K|    11   (0)| 00:00:01 |
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("A"="A")

实际上,通过我们测试可以发现,本质上应用SQL出问题,不是我们调整参数的问题,而是应用SQL写法不规范导致。或者说应用表结构设计存在缺陷导致。实际上该SQL,我们不需要调整隐含参数,通过对表的column 添加非空约束即可。

Related posts:

  1. 10g中distinct加强以及anti jion,semi jion
  2. about subquery unnest/push pred

Viewing all articles
Browse latest Browse all 12

Latest Images

Pangarap Quotes

Pangarap Quotes

Vimeo 10.7.0 by Vimeo.com, Inc.

Vimeo 10.7.0 by Vimeo.com, Inc.

HANGAD

HANGAD

MAKAKAALAM

MAKAKAALAM

Doodle Jump 3.11.30 by Lima Sky LLC

Doodle Jump 3.11.30 by Lima Sky LLC

Trending Articles


Ang Nobela sa “From Darna to ZsaZsa Zaturnnah: Desire and Fantasy, Essays on...


Lola Bunny para colorear


Libros para colorear


Mandalas de flores para colorear


Dibujos para colorear de perros


Dromedario para colorear


mayabang Quotes, Torpe Quotes, tanga Quotes


Love Quotes Tagalog


Tropa Quotes


Mga Tala sa “Unang Siglo ng Nobela sa Filipinas” (2009) ni Virgilio S. Almario


Gwapo Quotes : Babaero Quotes


Kung Fu Panda para colorear


Girasoles para colorear


Tiburon para colorear


Renos para colorear


Lagarto para colorear


Long Distance Relationship Tagalog Love Quotes


Tagalog Long Distance Relationship Love Quotes


RE: Mutton Pies (mely)


El Vibora (1971) by Francisco V. Coching and Federico C. Javinal



Latest Images

Pangarap Quotes

Pangarap Quotes

Vimeo 10.7.0 by Vimeo.com, Inc.

Vimeo 10.7.0 by Vimeo.com, Inc.

HANGAD

HANGAD

MAKAKAALAM

MAKAKAALAM

Doodle Jump 3.11.30 by Lima Sky LLC

Doodle Jump 3.11.30 by Lima Sky LLC