PHP内联sql比存储过程快得多

时间:2018-02-27 03:11:01

标签: php oracle stored-procedures oci8

我正在使用我们的DBA将所有php内联sql转换为存储过程。我发现执行与原始内联sql相同的sql的存储过程运行得慢得多。例如,我有1个查询,它将在1秒内联运行,而10秒通过存储过程运行。另一个在8秒内联运行,15分钟通过存储过程运行。有谁知道为什么两者之间存在这样的性能差异?

我正在运行php 5.6.33-1

OCI8 Support    enabled  
OCI8 DTrace Support disabled  
OCI8 Version    2.0.9  
Revision    $Id: 74e302c766329dcc183df9ea0359f733df8d192c $  
Oracle Run-time Client Library Version  11.2.0.4.0  
Oracle Compile-time Instant Client Version  11.2  
Directive   Local Value Master Value  
oci8.connection_class   no value    no value  
oci8.default_prefetch   100 100  
oci8.events Off Off  
oci8.max_persistent -1  -1  
oci8.old_oci_close_semantics    Off Off  
oci8.persistent_timeout -1  -1  
oci8.ping_interval  60  60  
oci8.privileged_connect Off Off  
oci8.statement_cache_size   20  20  

Statistics  
Active Persistent Connections   1  
Active Connections  1  

这是代码

function runSP($cid) {
        $conn = oci_connect('XXX', 'XXX', 'XXX');
        $stid = oci_parse($conn, 'begin WEB.XXSD_WEB_OVERVIEW.CUSTOMER_INVOICES (:cid,:rc,:err); end;');
        $refcur = oci_new_cursor($conn);
        oci_bind_by_name($stid, ':cid',$cid);
        oci_bind_by_name($stid, ':rc', $refcur, -1, OCI_B_CURSOR);
        oci_bind_by_name($stid, ':err',$err, 100);
        oci_execute($stid);

        oci_set_prefetch($refcur, 200);
        oci_execute($refcur);
        $rows = [];
        while ($row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) {
            $rows[] = $row;
        }

        oci_free_statement($refcur);
        oci_free_statement($stid);
        oci_close($conn);
        return $rows;
    }

    function inlineSql($cid) {
        $sql = 'select  th.customer_trx_id customer_id, th.trx_number, aps.status, th.trx_date, th.purchase_order,
                  th.interface_header_attribute1 order_id, upper(cav.city) city, upper(cav.state) state,
                  aps.status, round(sysdate-aps.due_date) past_due, th.invoice_currency_code,
                  nvl(aps.amount_due_original,0) original,
                  -(nvl(aps.amount_applied,0)) receipts,
                  nvl(aps.amount_credited,0) credits,
                  nvl(aps.amount_adjusted,0) adjustments,
                  -(nvl(aps.discount_taken_earned,0) + nvl(aps.discount_taken_unearned,0)) discount,
                  nvl(aps.amount_due_remaining,0) balance
                from ar.ar_payment_schedules_all aps, ar.ra_customer_trx_all th, xxsd_cust_addr_v cav
                where
                th.customer_trx_id = aps.customer_trx_id
                and th.bill_to_customer_id = :cid
                and th.batch_source_id <> 1023
                and th.ship_to_site_use_id = cav.site_use_id(+)
                order by  trx_date desc';
        $conn = oci_connect('XXX', 'XXX', 'XXX');
        $stid = oci_parse($conn, $sql);
        oci_bind_by_name($stid, ':cid',$cid);
        oci_execute($stid);

        $rows = [];
        while ($row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) {
            $rows[] = $row;
        }

        oci_free_statement($stid);
        oci_close($conn);
        return $rows;
    }
runSP(182574); //super slow, 10+ seconds
inlineSql(182574); //1 second

这是我正在调用的存储过程:

PROCEDURE CUSTOMER_INVOICES (
      P_CUSTOMER_ID   IN     APPS.RA_CUSTOMER_TRX_ALL.BILL_TO_CUSTOMER_ID%TYPE DEFAULT NULL,
      P_REF_CURSOR       OUT SYS_REFCURSOR,
      X_ERR_MSG          OUT VARCHAR2)
   IS
   BEGIN
      OPEN P_REF_CURSOR FOR
           ---Params:    customer_id

           SELECT TH.CUSTOMER_TRX_ID CUSTOMER_ID,
                  TH.TRX_NUMBER,
                  APS.STATUS,
                  TH.TRX_DATE,
                  TH.PURCHASE_ORDER,
                  TH.INTERFACE_HEADER_ATTRIBUTE1 ORDER_ID,
                  UPPER (CAV.CITY) CITY,
                  UPPER (CAV.STATE) STATE,
                  APS.STATUS,
                  ROUND (SYSDATE - APS.DUE_DATE) PAST_DUE,
                  TH.INVOICE_CURRENCY_CODE,
                  NVL (APS.AMOUNT_DUE_ORIGINAL, 0) ORIGINAL,
                  - (NVL (APS.AMOUNT_APPLIED, 0)) RECEIPTS,
                  NVL (APS.AMOUNT_CREDITED, 0) CREDITS,
                  NVL (APS.AMOUNT_ADJUSTED, 0) ADJUSTMENTS,
                  - (  NVL (APS.DISCOUNT_TAKEN_EARNED, 0)
                     + NVL (APS.DISCOUNT_TAKEN_UNEARNED, 0))
                     DISCOUNT,
                  NVL (APS.AMOUNT_DUE_REMAINING, 0) BALANCE
             FROM AR.AR_PAYMENT_SCHEDULES_ALL APS,
                  AR.RA_CUSTOMER_TRX_ALL TH,
                  WEB.XXSD_CUST_ADDR_V CAV
            WHERE     TH.CUSTOMER_TRX_ID = APS.CUSTOMER_TRX_ID
                  AND TH.BILL_TO_CUSTOMER_ID = P_CUSTOMER_ID
                  AND TH.BATCH_SOURCE_ID <> 1023
                  AND TH.SHIP_TO_SITE_USE_ID = CAV.SITE_USE_ID(+)
         ORDER BY TRX_DATE DESC;
   EXCEPTION
      WHEN INVALID_CURSOR
      THEN
         X_ERR_MSG := 'INVALID_CURSOR';
      WHEN INVALID_NUMBER
      THEN
         X_ERR_MSG := 'INVALID_NUMBER';
      WHEN PROGRAM_ERROR
      THEN
         X_ERR_MSG := 'PROGRAM_ERROR';
      WHEN VALUE_ERROR
      THEN
         X_ERR_MSG := 'VALUE_ERROR';
      WHEN OTHERS
      THEN
         X_ERR_MSG := 'ERROR IN SQL';
   END;

0 个答案:

没有答案
相关问题