2016-03-24 26 views
-2

私は、請求書とその発送先をロケーションに取得するためのクライアント用のレポートを作成しています。現在のところ、クエリは非常に遅く、誰かがクエリを最適化する方法をアドバイスできると感謝しています。私はクエリに多くの外部結合を持っています、そして、これは問題かもしれないと私は信じています。Oracle SQL最適化

アドバイスをいただければ幸いです。

SELECT 
b.operating_unit, 
b.trading_partner, 
b.invoice_date, 
b.type, 
b.gl_date, 
b.invoice_num, 
b.invoice_id, 
b.quantity, 
b.unit_price, 
b.uom, 
b.invoice_currency_code, 
b.payment_method_code, 
b.terms, 
b.ITEM_DESCRIPTION, 
b.LINE_NUMBER, 
b.item_code, 
b.VAT_CODE, 
b.amount, 
b.invoice_amount, 
b.vat_amount, 
b.discount_amount, 
b.price_variance, 
b.total_amount, 
b.status, 
b.ship_to_location 
FROM(
SELECT 
a.operating_unit, 
a.trading_partner, 
a.invoice_date, 
a.type, 
a.gl_date, 
a.invoice_num, 
a.invoice_id, 
a.quantity, 
ROUND(a.unit_price,2) unit_price, 
a.uom, 
a.invoice_currency_code, 
a.payment_method_code, 
a.terms, 
a.LINE_NUMBER, 
a.ITEM_DESCRIPTION, 
a.item_code, 
a.VAT_CODE, 
--CASE WHEN a.status = 'CANCELLED' THEN NULL 
--ELSE a.VAT_CODE END AS VAT_CODE, 
sum(a.AMOUNT) amount, 
a.invoice_amount, 
sum(a.vat_amount) vat_amount, 
sum(a.discount_amount) discount_amount, 
sum(a.price_variance) price_variance, 
sum(a.total_amount) total_amount, 
CASE WHEN a.status = 'FULLY' THEN 'Fully Applied' 
WHEN a.status = 'UNAPPROVED' THEN 'Unvalidated' 
WHEN a.status = 'NEEDS REAPPROVAL' THEN 'Needs Revalidation' 
WHEN a.status = 'APPROVED' THEN 'Validated' 
WHEN a.status = 'NEVER APPROVED' THEN 'Never Validated' 
WHEN a.status = 'CANCELLED' THEN 'Cancelled' 
WHEN a.status = 'UNPAID' THEN 'Unpaid' 
WHEN a.status = 'AVAILABLE' THEN 'Available' 
END AS status, 
a.ship_to_location 
from(
Select 
    hz.name operating_unit, 
    aia.INVOICE_TYPE_LOOKUP_CODE type,  
    aps.vendor_name trading_partner,  
    aia.INVOICE_DATE,  
    aia.gl_date, 
    aia.invoice_num, 
    aia.INVOICE_AMOUNT,   
    aida.invoice_id, 
    APIDA.LINE_NUMBER, 
    APIDA.QUANTITY_INVOICED QUANTITY, 
    APIDA.UNIT_PRICE, 
    APIDA.UOM, 
    aia.INVOICE_CURRENCY_CODE, 
    aia.PAYMENT_METHOD_CODE,  
    apt.name terms, 
    APIDA.ITEM_DESCRIPTION, 
    APIDA.ITEM_CODE, 
    case when apida.line_type_lookup_code <> 'IPV' THEN APIDA.AMOUNT ELSE 0 END AS AMOUNT, 
    --case when aida.line_type_lookup_code = 'REC_TAX' THEN aida.RECOVERY_RATE_NAME END AS VAT_CODE, 
    APIDA.VAT_CODE, 
    APIDA.VAT_AMOUNT, 
    0 DISCOUNT_AMOUNT, 
    case when apida.line_type_lookup_code = 'IPV' THEN APIDA.AMOUNT ELSE 0 END AS PRICE_VARIANCE,  
    APIDA.TOTAL_AMOUNT, 
    APPS.AP_INVOICES_PKG.GET_APPROVAL_STATUS 
      (
      aia.INVOICE_ID 
      ,aia.INVOICE_AMOUNT 
      ,aia.PAYMENT_STATUS_FLAG 
      ,aia.INVOICE_TYPE_LOOKUP_CODE 
      ) status, 
    APIDA.SHIP_TO_LOCATION 
    --b.description ship_to_location 
from (SELECT AILA.INVOICE_ID, AILA.LINE_TYPE_LOOKUP_CODE, AILA.LINE_NUMBER, aila.TAX_CLASSIFICATION_CODE VAT_CODE, AILA.QUANTITY_INVOICED, AILA.UNIT_PRICE, AILA.UNIT_MEAS_LOOKUP_CODE UOM, X.invoice_distribution_id, X.Description ITEM_DESCRIPTION, msi.segment1 item_code, NVL(X.AMOUNT, 0) AMOUNT, NVL(B.TAX_AMOUNT,0) VAT_AMOUNT, (NVL(X.AMOUNT, 0) + NVL(B.TAX_AMOUNT,0)) TOTAL_AMOUNT,HR.DESCRIPTION SHIP_TO_LOCATION 
FROM ap_invoice_lines_all aila, ap_invoice_distributions_all X, MTL_SYSTEM_ITEMS msi, hr_locations hr, 
(SELECT A.INVOICE_ID, A.LINE_TYPE_LOOKUP_CODE, A.INVOICE_LINE_NUMBER, A.CHARGE_APPLICABLE_TO_DIST_ID, SUM(A.AMOUNT) TAX_AMOUNT 
     FROM ap_invoice_distributions_all A 
     WHERE 1=1 
     AND A.LINE_TYPE_LOOKUP_CODE = 'REC_TAX' 
     GROUP BY A.INVOICE_ID, A.LINE_TYPE_LOOKUP_CODE, A.INVOICE_LINE_NUMBER, A.CHARGE_APPLICABLE_TO_DIST_ID) B 
WHERE AILA.INVOICE_ID = X.INVOICE_ID(+) 
AND X.INVOICE_ID = B.INVOICE_ID(+) 
AND X.invoice_distribution_id = B.CHARGE_APPLICABLE_TO_DIST_ID(+) 
and msi.inventory_item_id(+) = aila.inventory_item_id 
AND AILA.SHIP_TO_LOCATION_ID = HR.SHIP_TO_LOCATION_ID 
and aila.line_number = X.INVOICE_LINE_NUMBER(+) 
AND AILA.LINE_TYPE_LOOKUP_CODE != 'REC_TAX' AND AILA.LINE_TYPE_LOOKUP_CODE != 'NONREC_TAX' 
--AND AILA.INVOICE_ID = '10T52233547' 
)APIDA, 
ap_invoice_distributions_all aida, ap_invoices_all aia, ap_suppliers aps, ap_terms apt, hr_organization_units hz 
where aia.invoice_id = aida.invoice_id(+) 
and aia.invoice_id = APIDA.invoice_id(+) 
and aps.vendor_id = aia.vendor_id 
and apt.term_id = aia.terms_id 
and hz.ORGANIZATION_ID = aia.org_id 
--and aia.invoice_NUM = '123456' 
--and aida.LINE_TYPE_LOOKUP_CODE = 'REC_TAX' 
/* Parameters */ 
and hz.ORGANIZATION_ID between NVL(:p_operating_unit_from, hz.ORGANIZATION_ID) and NVL(:p_operating_unit_to, hz.ORGANIZATION_ID) 
and aia.INVOICE_DATE between NVL(:p_invoice_date_from, aia.INVOICE_DATE) and NVL(:p_invoice_date_to, aia.INVOICE_DATE) 
and aps.vendor_id between NVL(:p_trading_partner_from, aps.vendor_id) and NVL(:p_trading_partner_to, aps.vendor_id) 
and aia.gl_date between NVL(:p_gl_date_from, aia.gl_date) and NVL(:p_gl_date_to, aia.gl_date) 
order by hz.name, aps.vendor_name, APIDA.SHIP_TO_LOCATION, APIDA.ITEM_DESCRIPTION)a 
group by a.operating_unit, 
a.trading_partner, 
a.invoice_date, 
a.gl_date, 
a.invoice_num, 
a.invoice_amount, 
a.invoice_id, 
a.invoice_currency_code, 
a.payment_method_code, 
a.terms, 
a.ITEM_DESCRIPTION, 
a.item_code, 
a.VAT_CODE, 
a.quantity, 
a.unit_price, 
a.LINE_NUMBER, 
a.uom, 
a.status, 
a.type, 
a.ship_to_location)b 
order by b.operating_unit, b.trading_partner, b.ship_to_location, b.invoice_date, b.gl_date, b.invoice_num, b.LINE_NUMBER 

答えて

0

サブクエリにはORDER BYが使用されていますが、サブクエリは効果がありませんので、削除する必要があります。オプティマイザがそれに気づいて無視していない場合、クエリの処理速度が向上します。

あなたが使用しているコンマ区切りの結合構文は、1980年代に標準でしたが、エラーが発生しやすく、読みにくいと考えられています。可読性と保守性のために、明示的な結合(例えばINNER JOINLEFT OUTER JOIN)に置き換えることができます。しかし、私はあなたの結合にエラーがないので、それ以外は何も得られません。

最も外側のクエリは余分ですが、減速を引き起こすものではありません。だから問題もない。

これは、いくつかの外部結合と2つのgroup by句を含む複雑なクエリです。明白なエラーはありません。 where句で使用されているカラムにインデックスがあるかどうかを確認します。いくつかの複合インデックスも必要な場合があります。私はすべてのIDがすでに索引付けされていると思います。

  • ap_invoice_lines_all(invoice_id、LINE_NUMBER)
  • ap_invoice_distributions_all(invoice_id、invoice_line_number)
  • ap_invoice_distributions_all(line_type_lookup_code)
+0

アドバイスをいただきありがとうございます。私の投稿に返信するあなたの努力を感謝します。 – oubinghose

0

私はOracle SQLの初心者です。私は調査をしましたが、問題は外側の結合ではなく、むしろ別個のもので起こりました。大量のデータをグループ化しソートしなければならず、これが遅延を引き起こしています。

私はこのコードを修正し、DISTINCTの使用を避けなければなりません。解決策があるときは、私のような他の初心者のためにここに投稿して、新しいことを学ぶことができます。

+0

全く 'DISTINCT'がクエリにありません:私は、次の3つの追加の索引を提案します与えられた。 –