我正在使用我们的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;