Oracle VIEW PUSHED PREDICATE案例分析

SELECT *
  FROM (SELECTA.INVOICE_ID,
               A.VENDOR_ID,
               A.INVOICE_NUM,
               A.INVOICE_AMOUNT,
               A.GL_DATE,
               A.INVOICE_CURRENCY_CODE,
               SUM(NVL(B.PREPAY_AMOUNT_APPLIED,0)) PAID_AMOUNT,
               A.INVOICE_AMOUNT -SUM(NVL(B.PREPAY_AMOUNT_APPLIED, 0)) REMAIN
          FROM ap.AP_INVOICES_ALL A,APPS.AP_UNAPPLY_PREPAYS_V B
         WHERE A.INVOICE_ID = B.INVOICE_ID(+)
           AND A.ORG_ID = 126 /*:B4*/
           AND A.SOURCE = 'OSM IMPORTED'/*:B3*/
           AND A.INVOICE_NUM BETWEEN NVL(/*:B2*/ null, A.INVOICE_NUM) AND
               NVL( /*:B1*/ null,A.INVOICE_NUM)
         GROUP BY A.INVOICE_ID,
                  A.INVOICE_NUM,
                  A.INVOICE_AMOUNT,
                  A.VENDOR_ID,
                  A.GL_DATE,
                  A.INVOICE_CURRENCY_CODE)
 WHERE REMAIN > 0 ;

B是一个视图,定义如下:

CREATE OR REPLACE VIEWAPPS.AP_UNAPPLY_PREPAYS_V AS
SELECT AID1.ROWIDROW_ID,
       AID1.INVOICE_ID INVOICE_ID,
       AID1.INVOICE_DISTRIBUTION_IDINVOICE_DISTRIBUTION_ID,
       AID1.PREPAY_DISTRIBUTION_IDPREPAY_DISTRIBUTION_ID,
       AID1.DISTRIBUTION_LINE_NUMBERPREPAY_DIST_NUMBER,
       (-1) * AID1.AMOUNTPREPAY_AMOUNT_APPLIED,
       nvl(AID2.PREPAY_AMOUNT_REMAINING,AID2.AMOUNT) PREPAY_AMOUNT_REMAINING,
       AID1.DIST_CODE_COMBINATION_IDDIST_CODE_COMBINATION_ID,
       AID1.ACCOUNTING_DATE ACCOUNTING_DATE,
       AID1.PERIOD_NAME PERIOD_NAME,
       AID1.SET_OF_BOOKS_ID SET_OF_BOOKS_ID,
       AID1.DESCRIPTION DESCRIPTION,
       AID1.PO_DISTRIBUTION_IDPO_DISTRIBUTION_ID,
       AID1.RCV_TRANSACTION_IDRCV_TRANSACTION_ID,
       AID1.ORG_ID ORG_ID,
       AI.INVOICE_NUM PREPAY_NUMBER,
       AI.VENDOR_ID VENDOR_ID,
       AI.VENDOR_SITE_ID VENDOR_SITE_ID,
       ATC.TAX_ID TAX_ID,
       ATC.NAME TAX_CODE,
       PH.SEGMENT1 PO_NUMBER,
       PV.VENDOR_NAME VENDOR_NAME,
       PV.SEGMENT1 VENDOR_NUMBER,
       PVS.VENDOR_SITE_CODE VENDOR_SITE_CODE,
       RSH.RECEIPT_NUM RECEIPT_NUMBER
  FROM AP_INVOICES              AI,
       AP_INVOICE_DISTRIBUTIONS AID1,
       AP_INVOICE_DISTRIBUTIONS AID2,
       AP_TAX_CODES             ATC,
       PO_VENDORS               PV,
       PO_VENDOR_SITES          PVS,
       PO_DISTRIBUTIONS         PD,
       PO_HEADERS               PH,
       PO_LINES                 PL,
       PO_LINE_LOCATIONS        PLL,
       RCV_TRANSACTIONS         RTXNS,
       RCV_SHIPMENT_HEADERS     RSH,
       RCV_SHIPMENT_LINES       RSL
WHEREAID1.PREPAY_DISTRIBUTION_ID = AID2.INVOICE_DISTRIBUTION_ID
   AND AI.INVOICE_ID = AID2.INVOICE_ID
   AND AID1.AMOUNT < 0
   AND nvl(AID1.REVERSAL_FLAG, 'N') != 'Y'
   AND AID1.TAX_CODE_ID = ATC.TAX_ID(+)
   AND AID1.LINE_TYPE_LOOKUP_CODE = 'PREPAY'
   AND AI.VENDOR_ID = PV.VENDOR_ID
   AND AI.VENDOR_SITE_ID = PVS.VENDOR_SITE_ID
   AND AID1.PO_DISTRIBUTION_ID =PD.PO_DISTRIBUTION_ID(+)
   AND PD.PO_HEADER_ID = PH.PO_HEADER_ID(+)
   AND PD.LINE_LOCATION_ID =PLL.LINE_LOCATION_ID(+)
   AND PLL.PO_LINE_ID = PL.PO_LINE_ID(+)
   AND AID1.RCV_TRANSACTION_ID =RTXNS.TRANSACTION_ID(+)
   AND RTXNS.SHIPMENT_LINE_ID =RSL.SHIPMENT_LINE_ID(+)
   AND RSL.SHIPMENT_HEADER_ID =RSH.SHIPMENT_HEADER_ID(+);

执行计划:
SQL>@$ORACLE_HOME/rdbms/admin/utlxpls

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-------------------------------------------------------------------------------------------------------------
| Id  | Operation                                   |  Name                         | Rows  | Bytes | Cost  |
-------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                            |                               |     1 |    69 |   722 |
|*  1 |  FILTER                                     |                               |       |       |       |
|   2 |   SORT GROUP BY                             |                               |     1 |    69 |   722 |
|   3 |    NESTED LOOPS OUTER                       |                               |     3 |   207 |   697 |
|*  4 |     TABLE ACCESS FULL                       | AP_INVOICES_ALL               |     3 |   153 |   694 |
|   5 |     VIEW PUSHED PREDICATE                   | AP_UNAPPLY_PREPAYS_V          |     1 |    18 |     1 |
|   6 |      NESTED LOOPS                           |                               |     1 |   372 |     3 |
|   7 |       NESTED LOOPS                          |                               |     1 |   368 |     3 |
|   8 |        NESTED LOOPS                         |                               |     1 |   361 |     2 |
|   9 |         NESTED LOOPS                        |                               |     1 |   347 |     1 |
|  10 |          NESTED LOOPS OUTER                 |                               |     1 |   334 |     1 |
|  11 |           NESTED LOOPS OUTER                |                               |     1 |   321 |     1 |
|  12 |            NESTED LOOPS OUTER               |                               |     1 |   295 |     1 |
|  13 |             NESTED LOOPS OUTER              |                               |     1 |   269 |     1 |
|  14 |              NESTED LOOPS OUTER             |                               |     1 |   243 |     1 |
|  15 |               NESTED LOOPS OUTER            |                               |     1 |   197 |     1 |
|  16 |                NESTED LOOPS OUTER           |                               |     1 |   157 |     1 |
|  17 |                 NESTED LOOPS OUTER          |                               |     1 |    98 |     1 |
|* 18 |                  TABLE ACCESS BY INDEX ROWID| AP_INVOICE_DISTRIBUTIONS_ALL  |     1 |    72 |     1 |
|* 19 |                   INDEX FULL SCAN           | AP_INVOICE_DISTRIBUTIONS_N20  |     1 |       |       |
|* 20 |                  TABLE ACCESS BY INDEX ROWID| AP_TAX_CODES_ALL              |     1 |    26 |       |
|* 21 |                   INDEX UNIQUE SCAN         | AP_TAX_CODES_U1               |     1 |       |       |
|* 22 |                 TABLE ACCESS BY INDEX ROWID | PO_DISTRIBUTIONS_ALL          |     1 |    59 |       |
|* 23 |                  INDEX UNIQUE SCAN          | PO_DISTRIBUTIONS_U1           |     1 |       |       |
|* 24 |                TABLE ACCESS BY INDEX ROWID  | PO_HEADERS_ALL                |     1 |    40 |       |
|* 25 |                 INDEX UNIQUE SCAN           | PO_HEADERS_U1                 |     1 |       |       |
|* 26 |               TABLE ACCESS BY INDEX ROWID   | PO_LINE_LOCATIONS_ALL         |     1 |    46 |       |
|* 27 |                INDEX UNIQUE SCAN            | PO_LINE_LOCATIONS_U1          |     1 |       |       |
|* 28 |              TABLE ACCESS BY INDEX ROWID    | PO_LINES_ALL                  |     1 |    26 |       |
|* 29 |               INDEX UNIQUE SCAN             | PO_LINES_U1                   |     1 |       |       |
|  30 |             TABLE ACCESS BY INDEX ROWID     | RCV_TRANSACTIONS              |     1 |    26 |       |
|* 31 |              INDEX UNIQUE SCAN              | RCV_TRANSACTIONS_U1           |     1 |       |       |
|  32 |            TABLE ACCESS BY INDEX ROWID      | RCV_SHIPMENT_LINES            |     1 |    26 |       |
|* 33 |             INDEX UNIQUE SCAN               | RCV_SHIPMENT_LINES_U1         |     1 |       |       |
|* 34 |           INDEX UNIQUE SCAN                 | RCV_SHIPMENT_HEADERS_U1       |     1 |    13 |       |
|* 35 |          TABLE ACCESS BY INDEX ROWID        | AP_INVOICE_DISTRIBUTIONS_ALL  |     1 |    13 |       |
|* 36 |           INDEX UNIQUE SCAN                 | AP_INVOICE_DISTRIBUTIONS_U2   |     1 |       |       |
|* 37 |         TABLE ACCESS BY INDEX ROWID         | AP_INVOICES_ALL               |     1 |    14 |     1 |
|* 38 |          INDEX UNIQUE SCAN                  | AP_INVOICES_U1                |     1 |       |       |
|* 39 |        TABLE ACCESS BY INDEX ROWID          | PO_VENDOR_SITES_ALL           |     1 |     7 |     1 |
|* 40 |         INDEX UNIQUE SCAN                   | PO_VENDOR_SITES_U1            |     1 |       |       |
|* 41 |       INDEX UNIQUE SCAN                     | PO_VENDORS_U1                 |     1 |     4 |       |
-------------------------------------------------------------------------------------------------------------

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

  1 - filter("A"."INVOICE_AMOUNT"-SUM(NVL("B"."PREPAY_AMOUNT_APPLIED",0))>0)
  4 - filter("A"."ORG_ID"=126 AND "A"."SOURCE"='OSM IMPORTED' AND
             "A"."INVOICE_NUM">=NVL(NULL,"A"."INVOICE_NUM") AND "A"."INVOICE_NUM"<=NVL(NULL,"A"."INVOICE_NUM"))
 18 - filter("A"."INVOICE_ID"="AP_INVOICE_DISTRIBUTIONS_ALL"."INVOICE_ID" AND
             "AP_INVOICE_DISTRIBUTIONS_ALL"."AMOUNT"<0 AND NVL("AP_INVOICE_DISTRIBUTIONS_ALL"."REVERSAL_FLAG",'N')<>'Y'
             AND "AP_INVOICE_DISTRIBUTIONS_ALL"."LINE_TYPE_LOOKUP_CODE"='PREPAY' AND
             NVL("AP_INVOICE_DISTRIBUTIONS_ALL"."ORG_ID",NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 19 - filter("AP_INVOICE_DISTRIBUTIONS_ALL"."PREPAY_DISTRIBUTION_ID" IS NOT NULL)
 20 - filter(NVL("AP_TAX_CODES_ALL"."ORG_ID"(+),NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 21 - access("AP_INVOICE_DISTRIBUTIONS_ALL"."TAX_CODE_ID"="AP_TAX_CODES_ALL"."TAX_ID"(+))
 22 - filter(NVL("PO_DISTRIBUTIONS_ALL"."ORG_ID"(+),NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 23 - access("AP_INVOICE_DISTRIBUTIONS_ALL"."PO_DISTRIBUTION_ID"="PO_DISTRIBUTIONS_ALL"."PO_DISTRIBUTION_ID"
             (+))
 24 - filter(NVL("PO_HEADERS_ALL"."ORG_ID"(+),NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 25 - access("PO_DISTRIBUTIONS_ALL"."PO_HEADER_ID"="PO_HEADERS_ALL"."PO_HEADER_ID"(+))
 26 - filter(NVL("PO_LINE_LOCATIONS_ALL"."ORG_ID"(+),NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 27 - access("PO_DISTRIBUTIONS_ALL"."LINE_LOCATION_ID"="PO_LINE_LOCATIONS_ALL"."LINE_LOCATION_ID"(+))
 28 - filter(NVL("PO_LINES_ALL"."ORG_ID"(+),NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 29 - access("PO_LINE_LOCATIONS_ALL"."PO_LINE_ID"="PO_LINES_ALL"."PO_LINE_ID"(+))
 31 - access("AP_INVOICE_DISTRIBUTIONS_ALL"."RCV_TRANSACTION_ID"="RTXNS"."TRANSACTION_ID"(+))
 33 - access("RTXNS"."SHIPMENT_LINE_ID"="RSL"."SHIPMENT_LINE_ID"(+))
 34 - access("RSL"."SHIPMENT_HEADER_ID"="RSH"."SHIPMENT_HEADER_ID"(+))
 35 - filter(NVL("AP_INVOICE_DISTRIBUTIONS_ALL"."ORG_ID",NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 36 - access("AP_INVOICE_DISTRIBUTIONS_ALL"."PREPAY_DISTRIBUTION_ID"="AP_INVOICE_DISTRIBUTIONS_ALL"."INVOICE
             _DISTRIBUTION_ID")
 37 - filter(NVL("AP_INVOICES_ALL"."ORG_ID",NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 38 - access("AP_INVOICES_ALL"."INVOICE_ID"="AP_INVOICE_DISTRIBUTIONS_ALL"."INVOICE_ID")
 39 - filter(NVL("PO_VENDOR_SITES_ALL"."ORG_ID",NVL(TO_NUMBER(DECODE(SUBSTRB(:B1,1,1),'
             ',NULL,SUBSTRB(:B2,1,10))),(-99)))=NVL(TO_NUMBER(DECODE(SUBSTRB(:B3,1,1),' ',NULL,SUBSTRB(:B4,1,10))),(-99)))
 40 - access("AP_INVOICES_ALL"."VENDOR_SITE_ID"="PO_VENDOR_SITES_ALL"."VENDOR_SITE_ID")
 41 - access("AP_INVOICES_ALL"."VENDOR_ID"="PV"."VENDOR_ID")

Note: cpu costing is off

个人分析思路:
1.该语句包含视图,要从执行计划中看是否发生视图合并以及谓词推入。
2.从执行计划id 5可以看出发生了谓词推入,没有发生视图合并。
3.从原SQL语句中找推入的谓词,看是否为连接列推入。
原语句中ap.AP_INVOICES_ALL A, APPS.AP_UNAPPLY_PREPAYS_V B表和视图的连接列为 A.INVOICE_ID = B.INVOICE_ID(+)
4.执行计划谓词过滤信息检索可以看到18行 filter(“A”.“INVOICE_ID”=“AP_INVOICE_DISTRIBUTIONS_ALL”.“INVOICE_ID”
AP_INVOICE_DISTRIBUTIONS_ALL表为视图中的表,也就是说18行发生了连接列谓词推入.
如果没有发生谓词推入那么谓词过滤信息应为 filter(“A”.“INVOICE_ID”=APPS.AP_UNAPPLY_PREPAYS_V.“INVOICE_ID”
在这种情况下问题就非常明显了
作为被驱动表的不能合并的视图,内部多个表关联,这种情况下不可以推,因为本身该视图整体返回结果rows少,但是视图中单表rows很多,这样谓词推入,就会导致视图中的该表被干好多次(驱动表返回行数)
在这里插入图片描述

解决方法:
加入hint走HASH连接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值