5

我的任务是改进我公司的现有代码/查询,

数据库版本

Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
"CORE   10.2.0.4.0  Production"
TNS for IBM/AIX RISC System/6000: Version 10.2.0.4.0 - Productio
NLSRTL Version 10.2.0.4.0 - Production

这就是问题所在 - 当执行下面的代码时,完成工作所花费的时间超过 4 小时,大约 7 到 8 小时。

在此处输入图像描述

3小时37分钟内395行数据

  SELECT DISTINCT GROUP_DIST_NUMBER, BEGIN_DATE, PRICE_DROP_DATE
    FROM (SELECT DISTINCT
                 G.GROUP_DIST_NUMBER,
                 TO_DATE (:B2, 'DD-MON-YYYY') BEGIN_DATE,
                 TO_DATE (:B2, 'DD-MON-YYYY') PRICE_DROP_DATE
            FROM POS_DISTI_GROUP G,
                 POS_CUST_XREF M,
                 S_CPT_SEQ_NO C,
                 PP_STD_PRICE P,
                 S_CPT_AUDIT A,
                 RPT_PRODUCT_VALUE_LEVEL L
           WHERE     G.END_DATE > TO_DATE (:B2, 'DD-MON-YYYY')
                 AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
                 AND M.SG_BILL_TO_CUST_NO = A.BILL_TO_CUST_NO
                 AND A.START_DATE <= TO_DATE (:B2, 'DD-MON-YYYY')
                 AND A.END_DATE >= TO_DATE (:B2, 'DD-MON-YYYY')
                 AND L.PROD_VALUE = P.PROD_VALUE
                 AND L.PROD_LEVEL = P.PROD_LEVEL
                 AND C.CPT_PRICE_CODE IN
                        (SELECT /*+ PRECOMPUTE_SUBQUERY */
                                DISTINCT C1.CPT_PRICE_CODE
                           FROM PP_STD_PRICE P1,
                                S_CPT_PRICE_CODE C1,
                                S_CPT_SEQ_NO S1
                          WHERE     P1.STDP_ID = :B1
                                AND C1.CPT_PRICE_CAT LIKE 'NB%'
                                AND C1.CPT_PRICE_CODE = S1.CPT_PRICE_CODE
                                AND S1.PRICE_PROTECTABLE = 'Y')
                 AND C.CPT_PRICE_CODE = P.CUST_PRICE_TYPE
                 AND P.STDP_ID = :B1
                 AND A.CUST_PRICE_TYPE = C.CPT_BILL_CODE
                 AND M.ACTIVE_IND != 'N'
                 AND (M.CATEGORY_TYPE LIKE 'DIRECT%' OR M.INDIRECT_DISTI = 'Y')
                 AND TRUNC (M.ARCHIVE_DATE) > TRUNC (SYSDATE)
          UNION
            SELECT G.GROUP_DIST_NUMBER,
                   P.BEGIN_DATE,
                   MIN (INVT.PRICE_DROP_DATE) PRICE_DROP_DATE
              FROM POS_DISTI_GROUP G,
                   POS_CUST_XREF M,
                   PP_DEBIT_AUTHORIZATION P,
                   RPT_PRODUCT_VALUE_LEVEL L,
                   POS_PP_INVENTORY INVT
             WHERE     G.END_DATE > TO_DATE (:B2, 'DD-MON-YYYY')
                   AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
                   AND M.ACTIVE_IND != 'N'
                   AND (M.CATEGORY_TYPE LIKE 'DIRECT%' OR M.INDIRECT_DISTI = 'Y')
                   AND G.DIST_NUMBER = P.DIST_NUMBER
                   AND L.PROD_VALUE = P.PROD_VALUE
                   AND L.PROD_LEVEL = P.PROD_LEVEL
                   AND P.BEGIN_DATE >= TO_DATE (:B2, 'DD-MON-YYYY') - 6
                   AND P.BEGIN_DATE <= TO_DATE (:B2, 'DD-MON-YYYY')
                   AND INVT.DIST_NUMBER = G.GROUP_DIST_NUMBER
                   AND INVT.STMODEL = L.MOD_DESC
                   AND INVT.PPCF_SHOW_DATE = P.BEGIN_DATE
                   AND P.PRICE_TYPE = 'I'
                   AND (   P.POS_PROCESSED_FLAG IS NULL
                        OR P.POS_PROCESSED_FLAG != 'C')
                   AND P.POS_PP_FLAG = 'Y'
                   AND TRUNC (M.ARCHIVE_DATE) > TRUNC (SYSDATE)
          GROUP BY G.GROUP_DIST_NUMBER, P.BEGIN_DATE)
ORDER BY GROUP_DIST_NUMBER;

我不知道如何调整此查询语句以提高性能并使其执行得更快

这里是解释计划

--------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                 | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Pstart| Pstop |
--------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                          |                             |   101 |  2525 |       | 24156  (10)|       |       |
|   1 |  SORT ORDER BY                            |                             |   101 |  2525 |       | 24156  (10)|       |       |
|   2 |   VIEW                                    |                             |   101 |  2525 |       | 24155  (10)|       |       |
|   3 |    SORT UNIQUE                            |                             |   101 | 17691 |       | 24155  (75)|       |       |
|   4 |     UNION-ALL                             |                             |       |       |       |            |       |       |
|*  5 |      HASH JOIN                            |                             |    10M|  1680M|       |  6446   (5)|       |       |
|*  6 |       TABLE ACCESS FULL                   | S_CPT_SEQ_NO                |   651 |  5208 |       |     5   (0)|       |       |
|*  7 |       HASH JOIN                           |                             |  2383K|   379M|       |  6318   (3)|       |       |
|*  8 |        TABLE ACCESS FULL                  | POS_DISTI_GROUP             |   100 |  1800 |       |     5   (0)|       |       |
|*  9 |        HASH JOIN                          |                             |  2396K|   340M|  4320K|  6283   (3)|       |       |
|  10 |         VIEW                              | RPT_PRODUCT_VALUE_LEVEL     |   138K|  2697K|       |  1905   (3)|       |       |
|  11 |          UNION-ALL                        |                             |       |       |       |            |       |       |
|* 12 |           HASH JOIN RIGHT OUTER           |                             | 13965 |   627K|       |    91   (5)|       |       |
|  13 |            INDEX FULL SCAN                | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |       |     1   (0)|       |       |
|* 14 |            HASH JOIN RIGHT OUTER          |                             | 13965 |   436K|       |    89   (4)|       |       |
|  15 |             INDEX FULL SCAN               | PK_S_CAP_GROUP              |     2 |     8 |       |     1   (0)|       |       |
|  16 |             TABLE ACCESS FULL             | SMA_STMODEL                 | 13965 |   381K|       |    87   (3)|       |       |
|* 17 |           HASH JOIN RIGHT OUTER           |                             | 14175 |  1065K|       |   158   (5)|       |       |
|  18 |            INDEX FAST FULL SCAN           | PK_S_FAMILY                 |  1366 |  5464 |       |     2   (0)|       |       |
|* 19 |            HASH JOIN RIGHT OUTER          |                             | 14175 |  1010K|       |   156   (5)|       |       |
|  20 |             INDEX FULL SCAN               | PK_F_MODPRODMGR             |    22 |    88 |       |     1   (0)|       |       |
|* 21 |             HASH JOIN                     |                             | 14175 |   955K|       |   154   (4)|       |       |
|  22 |              TABLE ACCESS FULL            | SMA_PRODUCTMODEL            | 14132 |   317K|       |    62   (2)|       |       |
|* 23 |              HASH JOIN RIGHT OUTER        |                             | 13965 |   627K|       |    91   (5)|       |       |
|  24 |               INDEX FULL SCAN             | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |       |     1   (0)|       |       |
|* 25 |               HASH JOIN RIGHT OUTER       |                             | 13965 |   436K|       |    89   (4)|       |       |
|  26 |                INDEX FULL SCAN            | PK_S_CAP_GROUP              |     2 |     8 |       |     1   (0)|       |       |
|  27 |                TABLE ACCESS FULL          | SMA_STMODEL                 | 13965 |   381K|       |    87   (3)|       |       |
|  28 |           MAT_VIEW ACCESS FULL            | RPT_PROD_MV                 |   109K|  1288K|       |  1656   (3)|       |       |
|* 29 |         HASH JOIN                         |                             |   141K|    17M|       |  3191   (3)|       |       |
|* 30 |          INDEX RANGE SCAN                 | UK_PP_STD_PRICE_STDP_ID     |  4128 |   108K|       |    23   (0)|       |       |
|* 31 |          HASH JOIN                        |                             |  5341 |   532K|       |  3165   (3)|       |       |
|* 32 |           TABLE ACCESS FULL               | POS_CUST_XREF               |    54 |  2268 |       |    25   (4)|       |       |
|* 33 |           HASH JOIN                       |                             |   193K|    11M|       |  3137   (3)|       |       |
|* 34 |            TABLE ACCESS FULL              | S_CPT_AUDIT                 |    68 |  2108 |       |    76   (4)|       |       |
|* 35 |            HASH JOIN                      |                             |   745K|    20M|       |  3052   (2)|       |       |
|  36 |             TABLE ACCESS FULL             | S_CPT_SEQ_NO                |  1301 | 16913 |       |     5   (0)|       |       |
|  37 |             MERGE JOIN CARTESIAN          |                             | 88205 |  1378K|       |  3037   (2)|       |       |
|* 38 |              INDEX RANGE SCAN             | UK_PP_STD_PRICE_STDP_ID     |  4128 | 20640 |       |    23   (0)|       |       |
|  39 |              BUFFER SORT                  |                             |    21 |   231 |       |  3014   (2)|       |       |
|* 40 |               TABLE ACCESS FULL           | S_CPT_PRICE_CODE            |    21 |   231 |       |     1   (0)|       |       |
|  41 |      HASH GROUP BY                        |                             |     1 |   191 |       | 16421   (5)|       |       |
|* 42 |       FILTER                              |                             |       |       |       |            |       |       |
|  43 |        NESTED LOOPS                       |                             |     1 |   191 |       | 16419   (5)|       |       |
|* 44 |         HASH JOIN                         |                             |     7 |  1176 |       | 16370   (5)|       |       |
|* 45 |          HASH JOIN                        |                             |    74 |  8584 |       |  4790   (3)|       |       |
|* 46 |           HASH JOIN                       |                             |    60 |  3780 |       |    31   (7)|       |       |
|* 47 |            TABLE ACCESS FULL              | POS_CUST_XREF               |    60 |  2100 |       |    25   (4)|       |       |
|* 48 |            TABLE ACCESS FULL              | POS_DISTI_GROUP             |   100 |  2800 |       |     5   (0)|       |       |
|* 49 |           TABLE ACCESS FULL               | PP_DEBIT_AUTHORIZATION      |   345 | 18285 |       |  4759   (3)|       |       |
|  50 |          PARTITION RANGE ALL              |                             | 18192 |   923K|       | 11579   (6)|     1 |    33 |
|* 51 |           INDEX FAST FULL SCAN            | POS_PP_INVENTORY_PK         | 18192 |   923K|       | 11579   (6)|     1 |    33 |
|* 52 |         VIEW                              | RPT_PRODUCT_VALUE_LEVEL     |     1 |    23 |       |     7   (0)|       |       |
|  53 |          UNION ALL PUSHED PREDICATE       |                             |       |       |       |            |       |       |
|* 54 |           FILTER                          |                             |       |       |       |            |       |       |
|  55 |            NESTED LOOPS OUTER             |                             |     1 |    46 |       |     2   (0)|       |       |
|  56 |             NESTED LOOPS OUTER            |                             |     1 |    42 |       |     2   (0)|       |       |
|  57 |              TABLE ACCESS BY INDEX ROWID  | SMA_STMODEL                 |     1 |    28 |       |     2   (0)|       |       |
|* 58 |               INDEX UNIQUE SCAN           | PK_SMA_STMODEL              |     1 |       |       |     1   (0)|       |       |
|* 59 |              INDEX UNIQUE SCAN            | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |       |     0   (0)|       |       |
|* 60 |             INDEX UNIQUE SCAN             | PK_S_CAP_GROUP              |     2 |     8 |       |     0   (0)|       |       |
|  61 |           NESTED LOOPS OUTER              |                             |     1 |    77 |       |     3   (0)|       |       |
|  62 |            NESTED LOOPS OUTER             |                             |     1 |    73 |       |     3   (0)|       |       |
|  63 |             NESTED LOOPS OUTER            |                             |     1 |    69 |       |     3   (0)|       |       |
|  64 |              NESTED LOOPS OUTER           |                             |     1 |    65 |       |     3   (0)|       |       |
|  65 |               NESTED LOOPS                |                             |     1 |    51 |       |     3   (0)|       |       |
|* 66 |                TABLE ACCESS BY INDEX ROWID| SMA_PRODUCTMODEL            |     1 |    23 |       |     2   (0)|       |       |
|* 67 |                 INDEX UNIQUE SCAN         | PK_SMA_PRODUCTMODEL         |     1 |       |       |     1   (0)|       |       |
|  68 |                TABLE ACCESS BY INDEX ROWID| SMA_STMODEL                 |     1 |    28 |       |     1   (0)|       |       |
|* 69 |                 INDEX UNIQUE SCAN         | PK_SMA_STMODEL              |     1 |       |       |     0   (0)|       |       |
|* 70 |               INDEX UNIQUE SCAN           | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |       |     0   (0)|       |       |
|* 71 |              INDEX UNIQUE SCAN            | PK_S_FAMILY                 |  1366 |  5464 |       |     0   (0)|       |       |
|* 72 |             INDEX UNIQUE SCAN             | PK_S_CAP_GROUP              |     2 |     8 |       |     0   (0)|       |       |
|* 73 |            INDEX UNIQUE SCAN              | PK_F_MODPRODMGR             |    22 |    88 |       |     0   (0)|       |       |
|* 74 |           MAT_VIEW ACCESS BY INDEX ROWID  | RPT_PROD_MV                 |     1 |    24 |       |     2   (0)|       |       |
|* 75 |            INDEX UNIQUE SCAN              | IDX_RPT_PROD_MV_PROD_NO     |     1 |       |       |     1   (0)|       |       |
--------------------------------------------------------------------------------------------------------------------------------------

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

   5 - access("C1"."CPT_PRICE_CODE"="S1"."CPT_PRICE_CODE")
   6 - filter("S1"."PRICE_PROTECTABLE"='Y')
   7 - access("G"."GROUP_DIST_NUMBER"="M"."DIST_NUMBER")
   8 - filter("G"."END_DATE">TO_DATE(:B2,'DD-MON-YYYY'))
   9 - access("L"."PROD_VALUE"="P"."PROD_VALUE" AND "L"."PROD_LEVEL"="P"."PROD_LEVEL")
  12 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  14 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  17 - access("SF"."FAMILY"(+)=SUBSTRB("PM"."MODEL",1,3))
  19 - access("PM"."DESIGN_APPLICATION"="DA"."DESIGN_APPLICATION"(+))
  21 - access("PM"."MOD_DESC"="ST"."MOD_DESC")
  23 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  25 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  29 - access("C"."CPT_PRICE_CODE"="P"."CUST_PRICE_TYPE")
  30 - access("P"."STDP_ID"=TO_NUMBER(:B1))
  31 - access("M"."SG_BILL_TO_CUST_NO"="A"."BILL_TO_CUST_NO")
  32 - filter("M"."SG_BILL_TO_CUST_NO" IS NOT NULL AND ("M"."INDIRECT_DISTI"='Y' OR "M"."CATEGORY_TYPE" LIKE 'DIRECT%') AND 
              "M"."ACTIVE_IND"<>'N' AND TRUNC(INTERNAL_FUNCTION("M"."ARCHIVE_DATE"))>TRUNC(SYSDATE@!))
  33 - access("A"."CUST_PRICE_TYPE"="C"."CPT_BILL_CODE")
  34 - filter("A"."START_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "A"."END_DATE">=TO_DATE(:B2,'DD-MON-YYYY'))
  35 - access("C"."CPT_PRICE_CODE"="C1"."CPT_PRICE_CODE")
  38 - access("P1"."STDP_ID"=TO_NUMBER(:B1))
  40 - filter("C1"."CPT_PRICE_CAT" LIKE 'NB%')
  42 - filter(TO_DATE(:B2,'DD-MON-YYYY')-6<=TO_DATE(:B2,'DD-MON-YYYY'))
  44 - access("INVT"."DIST_NUMBER"="G"."GROUP_DIST_NUMBER" AND "INVT"."PPCF_SHOW_DATE"="P"."BEGIN_DATE")
  45 - access("G"."DIST_NUMBER"="P"."DIST_NUMBER")
  46 - access("G"."GROUP_DIST_NUMBER"="M"."DIST_NUMBER")
  47 - filter(("M"."INDIRECT_DISTI"='Y' OR "M"."CATEGORY_TYPE" LIKE 'DIRECT%') AND "M"."ACTIVE_IND"<>'N' AND 
              TRUNC(INTERNAL_FUNCTION("M"."ARCHIVE_DATE"))>TRUNC(SYSDATE@!))
  48 - filter("G"."END_DATE">TO_DATE(:B2,'DD-MON-YYYY'))
  49 - filter("P"."PRICE_TYPE"='I' AND "P"."POS_PP_FLAG"='Y' AND ("P"."POS_PROCESSED_FLAG"<>'C' OR "P"."POS_PROCESSED_FLAG" 
              IS NULL) AND "P"."BEGIN_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "P"."BEGIN_DATE">=TO_DATE(:B2,'DD-MON-YYYY')-6)
  51 - filter("INVT"."PPCF_SHOW_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "INVT"."PPCF_SHOW_DATE">=TO_DATE(:B2,'DD-MON-YYYY')-6)
  52 - filter("L"."PROD_LEVEL"="P"."PROD_LEVEL")
  54 - filter("P"."PROD_VALUE"="INVT"."STMODEL")
  58 - access("ST"."MOD_DESC"="P"."PROD_VALUE")
  59 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  60 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  66 - filter("PM"."MOD_DESC"="INVT"."STMODEL")
  67 - access("PM"."MODEL"="P"."PROD_VALUE")
  69 - access("ST"."MOD_DESC"="INVT"."STMODEL")
  70 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  71 - access("SF"."FAMILY"(+)=SUBSTRB("PM"."MODEL",1,3))
  72 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  73 - access("PM"."DESIGN_APPLICATION"="DA"."DESIGN_APPLICATION"(+))
  74 - filter("MOD_DESC"="INVT"."STMODEL")
  75 - access("PROD_NO"="P"."PROD_VALUE")

Note
-----
   - 'PLAN_TABLE' is old version

和表的行数统计

    TABLE_Name              NUM_ROWS
    -----------             ---------
    POS_DISTI_GROUP          2009 
    POS_CUST_XREF            2801
    S_CPT_SEQ_NO             1301
    PP_STD_PRICE             2658450
    S_CPT_AUDIT            27200
    PP_DEBIT_AUTHORIZATION   1199420
    POS_PP_INVENTORY     7276850
    PP_STD_PRICE             2658450
    S_CPT_PRICE_CODE     192
    S_CPT_SEQ_NO             1301
    SMA_STMODEL          13965
    RPT_PROD_MV          109980

创建表语句。点击这里

表说明。点击这里

按照@jonearles 的建议,使用重新运行gather_plan_statistics 检索解释计划。点击这里

*来自谷歌文档的链接

4

3 回答 3

4

问题

聚合在执行计划中发生得太晚了。计划 ID 4 和 5 生成 130亿行,占执行时间的 95%。Oracle 错误地认为行数会更小,并且应该将较早的聚合合并在一起。

计划 ID 6 到 40 代表内联视图的前半部分,在UNION. 查询的那部分有两个DISTINCTs,但是执行计划的那部分没有聚合操作的类型。Oracle 错误地认为最好先加入所有内容并执行 one SORT UNIQUE,而不是执行多个SORT UNIQUEorHASH GROUP BY并组合结果。

重现问题

在没有完全导出的情况下完全重现这个问题几乎是不可能的。即使它只是一个中等复杂的 SQL 语句,也涉及到数千个变量。下面的代码仅演示了 Oracle 如何错误地合并聚合操作。

首先,创建两个简单的表。每个都有 100K 行。TEST1 的数字从 1 到 100000。TEST2 包含 100000 行,但只有一个不同的数字。为了人为地制定一个糟糕的计划,TEST2 上的统计数据收集得太早了。优化器认为TEST2 只有一行,但实际上有 100000。

drop table test1 purge;
drop table test2 purge;

create table test1(a number);
create table test2(a number);

insert into test1 select level from dual connect by level <= 100000;
insert into test2 values (1);
commit;

begin
    dbms_stats.gather_table_stats(user, 'test1');
    dbms_stats.gather_table_stats(user, 'test2');
end;
/

insert into test2 select 1 from dual connect by level <= 100000;
commit;

下面的示例查询检索所有不同的 TEST1.A,其中 A 也在不同的 TEST2.A 中。

默认情况下,使用人为错误的统计信息,Oracle 先连接表,然后执行HASH GROUP BYand HASH UNIQUE。这是一个糟糕的计划,它连接了 TEST2 中的所有 100K 值。最好执行第HASH GROUP BY一个然后只加入该表中的 1 行。

explain plan for
select distinct a from test1 where a in (select a from test2 group by a);

select * from table(dbms_xplan.display(format => 'outline'));

------------------------------------------------------------------------------
| Id  | Operation            | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |       |     1 |     8 |    79   (2)| 00:00:01 |
|   1 |  HASH UNIQUE         |       |     1 |     8 |    79   (2)| 00:00:01 |
|   2 |   HASH GROUP BY      |       |     1 |     8 |    79   (2)| 00:00:01 |
|*  3 |    HASH JOIN         |       |     1 |     8 |    79   (2)| 00:00:01 |
|   4 |     TABLE ACCESS FULL| TEST2 |     1 |     3 |     3   (0)| 00:00:01 |
|   5 |     TABLE ACCESS FULL| TEST1 |   100K|   488K|    76   (2)| 00:00:01 |
------------------------------------------------------------------------------

潜在的解决方案#1:提示

不幸的是,没有官方提示可以控制排序和分组发生的时间和地点。通过使用outline格式选项,我能够找到一些可能有用的提示:USE_HASH_AGGREGATIONOUTLINE_LEAFPLACE_DISTINCT. (这些提示真的很棘手——我在示例中使用 agroup by而不是另一个的原因distinct是因为我在提示方面遇到了很多麻烦PLACE_DISTINCT!)

使用这些未记录的提示可以制定更好的计划。TEST2 的结果HASH GROUP BY应该立即通过。这类似于统计数据准确时将产生的计划。

explain plan for
select /*+ USE_HASH_AGGREGATION(@"SEL$5DA710D3") OUTLINE_LEAF(@"SEL$683B0107") */
distinct a from test1 where a in (select a from test2 group by a);

select * from table(dbms_xplan.display(format => 'outline alias'));

----------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |          |     1 |     8 |    79   (2)| 00:00:01 |
|   1 |  HASH UNIQUE          |          |     1 |     8 |    79   (2)| 00:00:01 |
|*  2 |   HASH JOIN SEMI      |          |     1 |     8 |    79   (2)| 00:00:01 |
|   3 |    VIEW               | VW_NSO_1 |     1 |     3 |     3   (0)| 00:00:01 |
|   4 |     HASH GROUP BY     |          |     1 |     3 |     3   (0)| 00:00:01 |
|   5 |      TABLE ACCESS FULL| TEST2    |     1 |     3 |     3   (0)| 00:00:01 |
|   6 |    TABLE ACCESS FULL  | TEST1    |   100K|   488K|    76   (2)| 00:00:01 |
----------------------------------------------------------------------------------

潜在解决方案 #2:强制使用 ROWNUM 制定计划。

上面的一个更简单和更安全的版本是使用ROWNUM. ROWNUM是一个伪列,表示返回的行的顺序。当有一个ROWNUMOracle 时不能移动distinctgroup by因为它会影响那个顺序。

不幸的是,这个技巧需要额外的代码并在计划中生成额外的步骤。这些额外的步骤大多只是传递数据,不应该减慢完成的速度。

explain plan for
select distinct a from test1 where a in
(
    --Extra level only because we only want to project one column.
    --It's syntactically required, but the optimizer throws out this inline view.
    select a
    from
    (
        --The ROWNUM forces everything in this inline view to happen separately.
        select a, rownum
        from
        (
            select a from test2 group by a
        )
    )
);

select * from table(dbms_xplan.display(format => 'outline alias'));

---------------------------------------------------------------------------------
| Id  | Operation               | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |       |     1 |     8 |    79   (2)| 00:00:01 |
|   1 |  HASH UNIQUE            |       |     1 |     8 |    79   (2)| 00:00:01 |
|*  2 |   HASH JOIN SEMI        |       |     1 |     8 |    79   (2)| 00:00:01 |
|   3 |    VIEW                 |       |     1 |     3 |     3   (0)| 00:00:01 |
|   4 |     COUNT               |       |       |       |            |          |
|   5 |      VIEW               |       |     1 |     3 |     3   (0)| 00:00:01 |
|   6 |       HASH GROUP BY     |       |     1 |     3 |     3   (0)| 00:00:01 |
|   7 |        TABLE ACCESS FULL| TEST2 |     1 |     3 |     3   (0)| 00:00:01 |
|   8 |    TABLE ACCESS FULL    | TEST1 |   100K|   488K|    76   (2)| 00:00:01 |
---------------------------------------------------------------------------------

潜在解决方案#3:修正基数估计并希望最好。

如果估计的行数是准确的,那么计划几乎总是好的。当行估计相差很远时,找到执行计划的第一部分基数错误的地方。对于这个计划,它似乎是计划 ID 36。E-Rows 和 A-Rows 相差一个数量级:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                 | Name                        | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  OMem |  1Mem |  O/1/M   |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
...
|* 36 |             TABLE ACCESS FULL             | POS_CUST_XREF               |      1 |     54 |    579 |00:00:00.01 |     131 |      0 |       |       |          |

步骤 36 有一个涉及 SYSDATE 的复杂谓词。

  36 - filter(("M"."SG_BILL_TO_CUST_NO" IS NOT NULL AND ("M"."INDIRECT_DISTI"='Y' OR "M"."CATEGORY_TYPE" LIKE 'DIRECT%') AND "M"."ACTIVE_IND"<>'N' AND
              TRUNC(INTERNAL_FUNCTION("M"."ARCHIVE_DATE"))>TRUNC(SYSDATE@!)))

即使有最新的统计数据,这种情况也很难预测。动态采样可能会有所帮助。尝试使用这样的顶级提示重新运行查询:

SELECT /*+ dynamic_sampling(6) */ ...

解决这些早期差异通常会在计划的后期解决其他问题。这个例子只是基数不匹配的一个可能来源。可能需要其他技巧来改进其他基数估计。这可能是一种非常困难的方法,但它可以通过多种方式获得回报。

红鲱鱼

任何中等复杂的 SQL 语句都有许多潜在的改进。评论和答案中有几个好主意。但是在调整时,始终必须关注最慢的部分,而不是最容易修复的部分。这听起来很明显,但这是一个非常容易掉入的陷阱。这就是为什么我要求您使用/*+ gather_plan_statistics*/,这就是为什么我的答案只关注计划中实际时间较大的部分。

例如,在我之前的评论中,我建议查看NESTED LOOPSwhere ROWS=1。现在我们有了实际时间,我们知道该建议没有帮助。(虽然一般来说,您仍然应该对包含大表但 ROWS=1 的计划持怀疑态度。)

于 2013-11-19T07:16:12.473 回答
0

只是猜测,但看起来你的声明没有在 archive_date 列上使用索引
尝试使用

AND M.ARCHIVE_DATE > TRUNC (SYSDATE) + 1 - 1/24/60/60

代替

AND TRUNC (M.ARCHIVE_DATE) > TRUNC (SYSDATE)

您也应该将所有表格描述发布到问题中

SELECT                       /*+ PARALLEL (P,4) PARALLEL (L,4)*/
            DISTINCT
            G.GROUP_DIST_NUMBER,
            TO_DATE ( :B2,
                    'DD-MON-YYYY' )
                BEGIN_DATE,
            TO_DATE ( :B2,
                    'DD-MON-YYYY' )
                PRICE_DROP_DATE
       FROM
            POS_DISTI_GROUP G,
            POS_CUST_XREF M,
            S_CPT_SEQ_NO C,
            PP_STD_PRICE P,
            S_CPT_AUDIT A,
            RPT_PRODUCT_VALUE_LEVEL L
       WHERE 1=0 -- switched off
                G.END_DATE > TO_DATE ( :B2,
                                  'DD-MON-YYYY' )
            AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
            AND M.SG_BILL_TO_CUST_NO = A.BILL_TO_CUST_NO
            AND A.START_DATE <= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
            AND A.END_DATE >= TO_DATE ( :B2,
                                   'DD-MON-YYYY' )
            AND L.PROD_VALUE = P.PROD_VALUE
            AND L.PROD_LEVEL = P.PROD_LEVEL
            AND C.CPT_PRICE_CODE IN
                    (SELECT                    /*+  PARALLEL (P1,4)*/
                          DISTINCT C1.CPT_PRICE_CODE
                    FROM
                          PP_STD_PRICE P1,
                          S_CPT_PRICE_CODE C1,
                          S_CPT_SEQ_NO S1
                    WHERE
                             P1.STDP_ID = :B1
                          AND C1.CPT_PRICE_CAT LIKE 'NB%'
                          AND C1.CPT_PRICE_CODE = S1.CPT_PRICE_CODE
                          AND S1.PRICE_PROTECTABLE = 'Y')
            AND C.CPT_PRICE_CODE = P.CUST_PRICE_TYPE
            AND P.STDP_ID = :B1
            AND A.CUST_PRICE_TYPE = C.CPT_BILL_CODE
            AND M.ACTIVE_IND != 'N'
            AND ( M.CATEGORY_TYPE LIKE 'DIRECT%'
                OR M.INDIRECT_DISTI = 'Y' )
            AND TRUNC ( M.ARCHIVE_DATE ) > TRUNC ( SYSDATE )
       UNION
       SELECT                      /*+  PARALLEL (P,4) PARALLEL (L,4) */
            G.GROUP_DIST_NUMBER,
            P.BEGIN_DATE,
            MIN ( INVT.PRICE_DROP_DATE ) PRICE_DROP_DATE
       FROM
            POS_DISTI_GROUP G,
            POS_CUST_XREF M,
            PP_DEBIT_AUTHORIZATION P,
            RPT_PRODUCT_VALUE_LEVEL L,
            POS_PP_INVENTORY PARTITION ("F2011_Q2") INVT
       WHERE 1=0 -- switched off
                G.END_DATE > TO_DATE ( :B2,
                                  'DD-MON-YYYY' )
            AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
            AND M.ACTIVE_IND != 'N'
            AND ( M.CATEGORY_TYPE LIKE 'DIRECT%'
                OR M.INDIRECT_DISTI = 'Y' )
            AND G.DIST_NUMBER = P.DIST_NUMBER
            AND L.PROD_VALUE = P.PROD_VALUE
            AND L.PROD_LEVEL = P.PROD_LEVEL
            AND P.BEGIN_DATE >= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
                            - 6
            AND P.BEGIN_DATE <= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
            AND INVT.DIST_NUMBER = G.GROUP_DIST_NUMBER
            AND INVT.STMODEL = L.MOD_DESC
            AND INVT.PPCF_SHOW_DATE = P.BEGIN_DATE
            AND P.PRICE_TYPE = 'I'
            AND ( P.POS_PROCESSED_FLAG IS NULL
                OR P.POS_PROCESSED_FLAG != 'C' )
            AND P.POS_PP_FLAG = 'Y'
            AND TRUNC ( M.ARCHIVE_DATE ) > TRUNC ( SYSDATE )
       GROUP BY
            G.GROUP_DIST_NUMBER,
            P.BEGIN_DATE

来自 OP 的结果

尝试在此处关闭并打开后,结果 1. 关闭第一个条件 关闭第一个条件

2.关闭第二个条件 关闭 2nd where 条件

3.关闭第三个条件,它开始长时间运行,所以我猜第二个条件的选择查询在执行时需要很长时间 关闭 3rd where 条件

于 2013-11-12T09:06:24.977 回答
0

在重写查询之前,能否请您回复此查询的计划和运行时间?

跟进:

  1. 添加并行提示

  2. 在选择中添加分区子句

precompute_subquery 提示将从子查询部分中取出子查询文本,在递归调用上下文中单独触发它(在运行主查询之前),获取结果并将这些结果作为 OR 条件列表传递给主查询“过滤”条件。我认为这称为子查询展开,它与用于分布式查询的查询块解解析不同。我已经看到它用于 OLAP 查询。

由于这是一个未记录的提示,因此开发人员不应使用它!子查询实际上是在软解析期间执行的,因此如果子查询的结果集发生更改,同一个子游标的多次执行可能会返回错误的结果(除非 Oracle 总是以某种方式强制对这些游标进行另一次完整解析 - 在这种情况下,您最终会得到如果滥用此功能,则库缓存/共享池锁存器争用)。所以我将其删除并并行用于大表。

也不要使用 Order by 这会过度使用查询运行时间。

SELECT
      DISTINCT GROUP_DIST_NUMBER,
             BEGIN_DATE,
             PRICE_DROP_DATE
FROM
      (SELECT                       /*+ PARALLEL (P,4) PARALLEL (L,4)*/
            DISTINCT
            G.GROUP_DIST_NUMBER,
            TO_DATE ( :B2,
                    'DD-MON-YYYY' )
                BEGIN_DATE,
            TO_DATE ( :B2,
                    'DD-MON-YYYY' )
                PRICE_DROP_DATE
       FROM
            POS_DISTI_GROUP G,
            POS_CUST_XREF M,
            S_CPT_SEQ_NO C,
            PP_STD_PRICE P,
            S_CPT_AUDIT A,
            RPT_PRODUCT_VALUE_LEVEL L
       WHERE
                G.END_DATE > TO_DATE ( :B2,
                                  'DD-MON-YYYY' )
            AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
            AND M.SG_BILL_TO_CUST_NO = A.BILL_TO_CUST_NO
            AND A.START_DATE <= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
            AND A.END_DATE >= TO_DATE ( :B2,
                                   'DD-MON-YYYY' )
            AND L.PROD_VALUE = P.PROD_VALUE
            AND L.PROD_LEVEL = P.PROD_LEVEL
            AND C.CPT_PRICE_CODE IN
                    (SELECT                    /*+  PARALLEL (P1,4)*/
                          DISTINCT C1.CPT_PRICE_CODE
                    FROM
                          PP_STD_PRICE P1,
                          S_CPT_PRICE_CODE C1,
                          S_CPT_SEQ_NO S1
                    WHERE
                             P1.STDP_ID = :B1
                          AND C1.CPT_PRICE_CAT LIKE 'NB%'
                          AND C1.CPT_PRICE_CODE = S1.CPT_PRICE_CODE
                          AND S1.PRICE_PROTECTABLE = 'Y')
            AND C.CPT_PRICE_CODE = P.CUST_PRICE_TYPE
            AND P.STDP_ID = :B1
            AND A.CUST_PRICE_TYPE = C.CPT_BILL_CODE
            AND M.ACTIVE_IND != 'N'
            AND ( M.CATEGORY_TYPE LIKE 'DIRECT%'
                OR M.INDIRECT_DISTI = 'Y' )
            AND TRUNC ( M.ARCHIVE_DATE ) > TRUNC ( SYSDATE )
       UNION
       SELECT                      /*+  PARALLEL (P,4) PARALLEL (L,4) */
            G.GROUP_DIST_NUMBER,
            P.BEGIN_DATE,
            MIN ( INVT.PRICE_DROP_DATE ) PRICE_DROP_DATE
       FROM
            POS_DISTI_GROUP G,
            POS_CUST_XREF M,
            PP_DEBIT_AUTHORIZATION P,
            RPT_PRODUCT_VALUE_LEVEL L,
            POS_PP_INVENTORY PARTITION ("F2011_Q2") INVT
       WHERE
                G.END_DATE > TO_DATE ( :B2,
                                  'DD-MON-YYYY' )
            AND G.GROUP_DIST_NUMBER = M.DIST_NUMBER
            AND M.ACTIVE_IND != 'N'
            AND ( M.CATEGORY_TYPE LIKE 'DIRECT%'
                OR M.INDIRECT_DISTI = 'Y' )
            AND G.DIST_NUMBER = P.DIST_NUMBER
            AND L.PROD_VALUE = P.PROD_VALUE
            AND L.PROD_LEVEL = P.PROD_LEVEL
            AND P.BEGIN_DATE >= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
                            - 6
            AND P.BEGIN_DATE <= TO_DATE ( :B2,
                                    'DD-MON-YYYY' )
            AND INVT.DIST_NUMBER = G.GROUP_DIST_NUMBER
            AND INVT.STMODEL = L.MOD_DESC
            AND INVT.PPCF_SHOW_DATE = P.BEGIN_DATE
            AND P.PRICE_TYPE = 'I'
            AND ( P.POS_PROCESSED_FLAG IS NULL
                OR P.POS_PROCESSED_FLAG != 'C' )
            AND P.POS_PP_FLAG = 'Y'
            AND TRUNC ( M.ARCHIVE_DATE ) > TRUNC ( SYSDATE )
       GROUP BY
            G.GROUP_DIST_NUMBER,
            P.BEGIN_DATE);

解释计划

-------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                         | Name                        | Rows  | Bytes | Cost (%CPU)| Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                                  |                             |   101 |  2525 |  8500  (17)|       |       |        |      |            |
|   1 |  PX COORDINATOR                                   |                             |       |       |            |       |       |        |      |            |
|   2 |   PX SEND QC (RANDOM)                             | :TQ10005                    |   101 |  2525 |  8500  (17)|       |       |  Q1,05 | P->S | QC (RAND)  |
|   3 |    VIEW                                           |                             |   101 |  2525 |  8500  (17)|       |       |  Q1,05 | PCWP |            |
|   4 |     SORT UNIQUE                                   |                             |   101 | 18291 |  8500  (82)|       |       |  Q1,05 | PCWP |            |
|   5 |      PX RECEIVE                                   |                             |       |       |            |       |       |  Q1,05 | PCWP |            |
|   6 |       PX SEND HASH                                | :TQ10004                    |       |       |            |       |       |  Q1,04 | P->P | HASH       |
|   7 |        BUFFER SORT                                |                             |   101 |  2525 |            |       |       |  Q1,04 | PCWP |            |
|   8 |         UNION-ALL                                 |                             |       |       |            |       |       |  Q1,04 | PCWP |            |
|   9 |          BUFFER SORT                              |                             |       |       |            |       |       |  Q1,04 | PCWC |            |
|  10 |           PX RECEIVE                              |                             |       |       |            |       |       |  Q1,04 | PCWP |            |
|  11 |            PX SEND ROUND-ROBIN                    | :TQ10001                    |       |       |            |       |       |        | S->P | RND-ROBIN  |
|  12 |             MERGE JOIN CARTESIAN                  |                             |    10M|  1737M|  1635   (5)|       |       |        |      |            |
|* 13 |              HASH JOIN                            |                             |  2439 |   419K|   322   (3)|       |       |        |      |            |
|* 14 |               TABLE ACCESS FULL                   | POS_DISTI_GROUP             |   100 |  1800 |     5   (0)|       |       |        |      |            |
|* 15 |               HASH JOIN                           |                             |  2452 |   378K|   317   (3)|       |       |        |      |            |
|* 16 |                TABLE ACCESS FULL                  | S_CPT_SEQ_NO                |   651 |  5208 |     5   (0)|       |       |        |      |            |
|  17 |                NESTED LOOPS                       |                             |   580 | 87000 |   311   (2)|       |       |        |      |            |
|  18 |                 NESTED LOOPS                      |                             |    34 |  4658 |   131   (4)|       |       |        |      |            |
|* 19 |                  HASH JOIN                        |                             |     1 |    97 |   109   (5)|       |       |        |      |            |
|* 20 |                   HASH JOIN                       |                             |     9 |   774 |   107   (5)|       |       |        |      |            |
|* 21 |                    HASH JOIN                      |                             |     2 |   146 |   101   (4)|       |       |        |      |            |
|* 22 |                     TABLE ACCESS FULL             | POS_CUST_XREF               |    54 |  2268 |    25   (4)|       |       |        |      |            |
|* 23 |                     TABLE ACCESS FULL             | S_CPT_AUDIT                 |    68 |  2108 |    76   (4)|       |       |        |      |            |
|  24 |                    TABLE ACCESS FULL              | S_CPT_SEQ_NO                |  1301 | 16913 |     5   (0)|       |       |        |      |            |
|* 25 |                   TABLE ACCESS FULL               | S_CPT_PRICE_CODE            |    21 |   231 |     2   (0)|       |       |        |      |            |
|* 26 |                  INDEX RANGE SCAN                 | UK_PP_STD_PRICE_STDP_ID     |    26 |  1040 |    22   (0)|       |       |        |      |            |
|* 27 |                 VIEW                              | RPT_PRODUCT_VALUE_LEVEL     |     1 |    13 |     5   (0)|       |       |        |      |            |
|  28 |                  UNION ALL PUSHED PREDICATE       |                             |       |       |            |       |       |        |      |            |
|  29 |                   NESTED LOOPS OUTER              |                             |     1 |    46 |     2   (0)|       |       |        |      |            |
|  30 |                    NESTED LOOPS OUTER             |                             |     1 |    42 |     2   (0)|       |       |        |      |            |
|  31 |                     TABLE ACCESS BY INDEX ROWID   | SMA_STMODEL                 |     1 |    28 |     2   (0)|       |       |        |      |            |
|* 32 |                      INDEX UNIQUE SCAN            | PK_SMA_STMODEL              |     1 |       |     1   (0)|       |       |        |      |            |
|* 33 |                     INDEX UNIQUE SCAN             | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |     0   (0)|       |       |        |      |            |
|* 34 |                    INDEX UNIQUE SCAN              | PK_S_CAP_GROUP              |     2 |     8 |     0   (0)|       |       |        |      |            |
|  35 |                   NESTED LOOPS OUTER              |                             |     1 |    77 |     2   (0)|       |       |        |      |            |
|  36 |                    NESTED LOOPS OUTER             |                             |     1 |    73 |     2   (0)|       |       |        |      |            |
|  37 |                     NESTED LOOPS                  |                             |     1 |    59 |     2   (0)|       |       |        |      |            |
|  38 |                      NESTED LOOPS OUTER           |                             |     1 |    31 |     2   (0)|       |       |        |      |            |
|  39 |                       NESTED LOOPS OUTER          |                             |     1 |    27 |     2   (0)|       |       |        |      |            |
|  40 |                        TABLE ACCESS BY INDEX ROWID| SMA_PRODUCTMODEL            |     1 |    23 |     2   (0)|       |       |        |      |            |
|* 41 |                         INDEX UNIQUE SCAN         | PK_SMA_PRODUCTMODEL         |     1 |       |     1   (0)|       |       |        |      |            |
|* 42 |                        INDEX UNIQUE SCAN          | PK_S_FAMILY                 |  1366 |  5464 |     0   (0)|       |       |        |      |            |
|* 43 |                       INDEX UNIQUE SCAN           | PK_F_MODPRODMGR             |    22 |    88 |     0   (0)|       |       |        |      |            |
|  44 |                      TABLE ACCESS BY INDEX ROWID  | SMA_STMODEL                 | 13965 |   381K|     1   (0)|       |       |        |      |            |
|* 45 |                       INDEX UNIQUE SCAN           | PK_SMA_STMODEL              |     1 |       |     0   (0)|       |       |        |      |            |
|* 46 |                     INDEX UNIQUE SCAN             | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |     0   (0)|       |       |        |      |            |
|* 47 |                    INDEX UNIQUE SCAN              | PK_S_CAP_GROUP              |     2 |     8 |     0   (0)|       |       |        |      |            |
|* 48 |                   INDEX UNIQUE SCAN               | IDX_RPT_PROD_MV_PROD_NO     |     1 |    12 |     1   (0)|       |       |        |      |            |
|  49 |              BUFFER SORT                          |                             |  4128 | 20640 |  1629   (5)|       |       |        |      |            |
|* 50 |               INDEX RANGE SCAN                    | UK_PP_STD_PRICE_STDP_ID     |  4128 | 20640 |    23   (0)|       |       |        |      |            |
|  51 |          HASH GROUP BY                            |                             |     1 |   191 |  5578   (2)|       |       |  Q1,04 | PCWP |            |
|  52 |           PX RECEIVE                              |                             |     1 |   191 |  5578   (2)|       |       |  Q1,04 | PCWP |            |
|  53 |            PX SEND HASH                           | :TQ10003                    |     1 |   191 |  5578   (2)|       |       |  Q1,03 | P->P | HASH       |
|  54 |             HASH GROUP BY                         |                             |     1 |   191 |  5578   (2)|       |       |  Q1,03 | PCWP |            |
|* 55 |              FILTER                               |                             |       |       |            |       |       |  Q1,03 | PCWC |            |
|  56 |               NESTED LOOPS                        |                             |     1 |   191 |  5575   (2)|       |       |  Q1,03 | PCWP |            |
|  57 |                NESTED LOOPS                       |                             |     7 |  1176 |  5562   (2)|       |       |  Q1,03 | PCWP |            |
|* 58 |                 HASH JOIN                         |                             |    74 |  8584 |  1347   (3)|       |       |  Q1,03 | PCWP |            |
|  59 |                  BUFFER SORT                      |                             |       |       |            |       |       |  Q1,03 | PCWC |            |
|  60 |                   PX RECEIVE                      |                             |    60 |  3780 |    31   (7)|       |       |  Q1,03 | PCWP |            |
|  61 |                    PX SEND HASH                   | :TQ10000                    |    60 |  3780 |    31   (7)|       |       |        | S->P | HASH       |
|* 62 |                     HASH JOIN                     |                             |    60 |  3780 |    31   (7)|       |       |        |      |            |
|* 63 |                      TABLE ACCESS FULL            | POS_CUST_XREF               |    60 |  2100 |    25   (4)|       |       |        |      |            |
|* 64 |                      TABLE ACCESS FULL            | POS_DISTI_GROUP             |   100 |  2800 |     5   (0)|       |       |        |      |            |
|  65 |                  PX RECEIVE                       |                             |   345 | 18285 |  1316   (2)|       |       |  Q1,03 | PCWP |            |
|  66 |                   PX SEND HASH                    | :TQ10002                    |   345 | 18285 |  1316   (2)|       |       |  Q1,02 | P->P | HASH       |
|  67 |                    PX BLOCK ITERATOR              |                             |   345 | 18285 |  1316   (2)|       |       |  Q1,02 | PCWC |            |
|* 68 |                     TABLE ACCESS FULL             | PP_DEBIT_AUTHORIZATION      |   345 | 18285 |  1316   (2)|       |       |  Q1,02 | PCWP |            |
|  69 |                 PARTITION RANGE ALL               |                             |     1 |    52 |   205   (1)|     1 |    33 |  Q1,03 | PCWP |            |
|* 70 |                  INDEX RANGE SCAN                 | POS_PP_INVENTORY_PK         |     1 |    52 |   205   (1)|     1 |    33 |  Q1,03 | PCWP |            |
|* 71 |                VIEW                               | RPT_PRODUCT_VALUE_LEVEL     |     1 |    23 |     7   (0)|       |       |  Q1,03 | PCWP |            |
|  72 |                 UNION ALL PUSHED PREDICATE        |                             |       |       |            |       |       |  Q1,03 | PCWP |            |
|* 73 |                  FILTER                           |                             |       |       |            |       |       |  Q1,03 | PCWP |            |
|  74 |                   NESTED LOOPS OUTER              |                             |     1 |    46 |     2   (0)|       |       |  Q1,03 | PCWP |            |
|  75 |                    NESTED LOOPS OUTER             |                             |     1 |    42 |     2   (0)|       |       |  Q1,03 | PCWP |            |
|  76 |                     TABLE ACCESS BY INDEX ROWID   | SMA_STMODEL                 |     1 |    28 |     2   (0)|       |       |  Q1,03 | PCWP |            |
|* 77 |                      INDEX UNIQUE SCAN            | PK_SMA_STMODEL              |     1 |       |     1   (0)|       |       |  Q1,03 | PCWP |            |
|* 78 |                     INDEX UNIQUE SCAN             | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 79 |                    INDEX UNIQUE SCAN              | PK_S_CAP_GROUP              |     2 |     8 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|  80 |                  NESTED LOOPS OUTER               |                             |     1 |    77 |     3   (0)|       |       |  Q1,03 | PCWP |            |
|  81 |                   NESTED LOOPS OUTER              |                             |     1 |    73 |     3   (0)|       |       |  Q1,03 | PCWP |            |
|  82 |                    NESTED LOOPS OUTER             |                             |     1 |    69 |     3   (0)|       |       |  Q1,03 | PCWP |            |
|  83 |                     NESTED LOOPS OUTER            |                             |     1 |    65 |     3   (0)|       |       |  Q1,03 | PCWP |            |
|  84 |                      NESTED LOOPS                 |                             |     1 |    51 |     3   (0)|       |       |  Q1,03 | PCWP |            |
|* 85 |                       TABLE ACCESS BY INDEX ROWID | SMA_PRODUCTMODEL            |     1 |    23 |     2   (0)|       |       |  Q1,03 | PCWP |            |
|* 86 |                        INDEX UNIQUE SCAN          | PK_SMA_PRODUCTMODEL         |     1 |       |     1   (0)|       |       |  Q1,03 | PCWP |            |
|  87 |                       TABLE ACCESS BY INDEX ROWID | SMA_STMODEL                 |     1 |    28 |     1   (0)|       |       |  Q1,03 | PCWP |            |
|* 88 |                        INDEX UNIQUE SCAN          | PK_SMA_STMODEL              |     1 |       |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 89 |                      INDEX UNIQUE SCAN            | PK_SEAEGO_PRODUCT_HIERARCHY |   298 |  4172 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 90 |                     INDEX UNIQUE SCAN             | PK_S_FAMILY                 |  1366 |  5464 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 91 |                    INDEX UNIQUE SCAN              | PK_S_CAP_GROUP              |     2 |     8 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 92 |                   INDEX UNIQUE SCAN               | PK_F_MODPRODMGR             |    22 |    88 |     0   (0)|       |       |  Q1,03 | PCWP |            |
|* 93 |                  MAT_VIEW ACCESS BY INDEX ROWID   | RPT_PROD_MV                 |     1 |    24 |     2   (0)|       |       |  Q1,03 | PCWP |            |
|* 94 |                   INDEX UNIQUE SCAN               | IDX_RPT_PROD_MV_PROD_NO     |     1 |       |     1   (0)|       |       |  Q1,03 | PCWP |            |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------

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

  13 - access("G"."GROUP_DIST_NUMBER"="M"."DIST_NUMBER")
  14 - filter("G"."END_DATE">TO_DATE(:B2,'DD-MON-YYYY'))
  15 - access("C1"."CPT_PRICE_CODE"="S1"."CPT_PRICE_CODE")
  16 - filter("S1"."PRICE_PROTECTABLE"='Y')
  19 - access("C"."CPT_PRICE_CODE"="C1"."CPT_PRICE_CODE")
  20 - access("A"."CUST_PRICE_TYPE"="C"."CPT_BILL_CODE")
  21 - access("M"."SG_BILL_TO_CUST_NO"="A"."BILL_TO_CUST_NO")
  22 - filter("M"."SG_BILL_TO_CUST_NO" IS NOT NULL AND ("M"."INDIRECT_DISTI"='Y' OR "M"."CATEGORY_TYPE" LIKE 'DIRECT%') AND "M"."ACTIVE_IND"<>'N' AND 
              TRUNC(INTERNAL_FUNCTION("M"."ARCHIVE_DATE"))>TRUNC(SYSDATE@!))
  23 - filter("A"."START_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "A"."END_DATE">=TO_DATE(:B2,'DD-MON-YYYY'))
  25 - filter("C1"."CPT_PRICE_CAT" LIKE 'NB%')
  26 - access("P"."STDP_ID"=TO_NUMBER(:B1) AND "C"."CPT_PRICE_CODE"="P"."CUST_PRICE_TYPE")
       filter("C"."CPT_PRICE_CODE"="P"."CUST_PRICE_TYPE")
  27 - filter("L"."PROD_LEVEL"="P"."PROD_LEVEL")
  32 - access("ST"."MOD_DESC"="P"."PROD_VALUE")
  33 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  34 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  41 - access("PM"."MODEL"="P"."PROD_VALUE")
  42 - access("SF"."FAMILY"(+)=SUBSTRB("PM"."MODEL",1,3))
  43 - access("PM"."DESIGN_APPLICATION"="DA"."DESIGN_APPLICATION"(+))
  45 - access("PM"."MOD_DESC"="ST"."MOD_DESC")
  46 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  47 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  48 - access("PROD_NO"="P"."PROD_VALUE")
  50 - access("P1"."STDP_ID"=TO_NUMBER(:B1))
  55 - filter(TO_DATE(:B2,'DD-MON-YYYY')-6<=TO_DATE(:B2,'DD-MON-YYYY'))
  58 - access("G"."DIST_NUMBER"="P"."DIST_NUMBER")
  62 - access("G"."GROUP_DIST_NUMBER"="M"."DIST_NUMBER")
  63 - filter(("M"."INDIRECT_DISTI"='Y' OR "M"."CATEGORY_TYPE" LIKE 'DIRECT%') AND "M"."ACTIVE_IND"<>'N' AND 
              TRUNC(INTERNAL_FUNCTION("M"."ARCHIVE_DATE"))>TRUNC(SYSDATE@!))
  64 - filter("G"."END_DATE">TO_DATE(:B2,'DD-MON-YYYY'))
  68 - filter("P"."PRICE_TYPE"='I' AND "P"."POS_PP_FLAG"='Y' AND ("P"."POS_PROCESSED_FLAG"<>'C' OR "P"."POS_PROCESSED_FLAG" IS NULL) AND 
              "P"."BEGIN_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "P"."BEGIN_DATE">=TO_DATE(:B2,'DD-MON-YYYY')-6)
  70 - access("INVT"."DIST_NUMBER"="G"."GROUP_DIST_NUMBER" AND "INVT"."PPCF_SHOW_DATE"="P"."BEGIN_DATE")
       filter("INVT"."PPCF_SHOW_DATE"<=TO_DATE(:B2,'DD-MON-YYYY') AND "INVT"."PPCF_SHOW_DATE">=TO_DATE(:B2,'DD-MON-YYYY')-6 AND 
              "INVT"."PPCF_SHOW_DATE"="P"."BEGIN_DATE")
  71 - filter("L"."PROD_LEVEL"="P"."PROD_LEVEL")
  73 - filter("P"."PROD_VALUE"="INVT"."STMODEL")
  77 - access("ST"."MOD_DESC"="P"."PROD_VALUE")
  78 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  79 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  85 - filter("PM"."MOD_DESC"="INVT"."STMODEL")
  86 - access("PM"."MODEL"="P"."PROD_VALUE")
  88 - access("ST"."MOD_DESC"="INVT"."STMODEL")
  89 - access("ST"."MARKETING_NAME"="PH"."MARKETING_NAME"(+))
  90 - access("SF"."FAMILY"(+)=SUBSTRB("PM"."MODEL",1,3))
  91 - access("ST"."MOD_CAPACITY_FORMATTED"="SCG"."MOD_CAPACITY_FORMATTED"(+))
  92 - access("PM"."DESIGN_APPLICATION"="DA"."DESIGN_APPLICATION"(+))
  93 - filter("MOD_DESC"="INVT"."STMODEL")
  94 - access("PROD_NO"="P"."PROD_VALUE")

Note
-----
   - 'PLAN_TABLE' is old version

PS: 你设法获得运行时间吗?我也更改了查询,请对此进行测试并告诉我们结果。理想情况下,第一个查询应该比你的要快,第二个(替换第一个)应该比第一个更好。记住将它们分开保存,并附上性能说明。

于 2013-11-13T09:16:08.440 回答