2012-12-19 41 views
0

我有53個字符串的代碼查詢,我需要優化它。我有PL/SQL Developer 7.0工具,我應該如何使用它進行優化?如何使用PL/SQL Developer優化查詢?

我試着使用解釋計劃,但它沒有告訴我什麼。我還添加了時間和時間戳列,但沒有什麼有趣的,第一個是空的,第二個總是在同一時間。

我嘗試使用測試窗口,但過程中,需要插入變量,並作爲我的查詢選擇我不能用它多行。

所以問題是我如何使用PL/SQL Developer優化SQL查詢?我應該在哪裏查找每個子查詢的查詢執行時間?也許有一些指南,但是現在我只找到了一些文檔,但是這對我來說並不有用?根據我目前的知識,在沒有任何工具的情況下優化這樣的大查詢似乎是不可能的

查詢,需要優化:

select count(PRODUCT_NUMBER) 
    from 
(select W.SUID, 
     I.SUID, 
     W.PRODUCT_NUMBER, 
     MI.ML_NUMBER, 
     I.TITLE_TRANSLIT, 
     I.COUNTRIES, 
     QTY.REMAINS, 
     QTY.ACQ_PRICE_USD, 
     QTY.REMAINS * QTY.ACQ_PRICE_USD as TOTAL 
    from (select UID_WARE, 
       QTY as REMAINS, 
       ACQ_PRICE_USD 
      from (select UID_WARE, 
         PRODUCT_NUMBER, 
         NVL(sum(QTY_ON_STOCK), 0) - NVL(sum(ADD_IN_QTY), 0) + NVL(sum(ADD_OUT_QTY), 0) as QTY, 
         ACQ_PRICE_USD as ACQ_PRICE_USD 
        from (select SI.UID_WARE, 
           W.PRODUCT_NUMBER, 
           count(distinct STK.SUID) as QTY_ON_STOCK, 
           sum(case 
            when 1 = 1 then 
             DECODE('' , SM.UID_SOURCE_LOCATION, SM.QTY, 0) 
            else 0 
            end) as ADD_OUT_QTY, 
           sum(case 
            when 1 = 1 then 
             DECODE('' , SM.UID_DEST_LOCATION, SM.QTY, 0) 
            else 0 
            end) as ADD_IN_QTY, 
           ROUND(ACQ.PRICE_USD, 2) as ACQ_PRICE_USD 
          from STOCK_MOVEMENTS SM 
          join STOCK_ITEMS SI on SM.UID_STOCK_ITEM = SI.SUID 
          left outer join (select PR.UID_STOCK_ITEM, 
               DECODE(NVL(CR.RATE, 0), 0, 0, PR.PRICE/CR.RATE) as PRICE_USD 
              from MV_STOCK_ACQ_PRICES PR, 
               CURRENCY_RATES CR 
              where PR.PRICE_DATE = CR.RATE_DATE 
               and PR.UID_CURRENCY = CR.UID_CURRENCY) ACQ on ACQ.UID_STOCK_ITEM = SI.SUID 
          join WARES W on W.SUID = SI.UID_WARE 
          left outer join (select distinct STK.SUID, 
                  STK.QTY_REMAINS 
              from STOCK_ITEMS STK 
              where STK.UID_STOCK_LOCATION != 'MS-STL-SALED' 
               ) STK on STK.SUID = SI.SUID 
         where 1 = 1 

         group by SI.UID_WARE, 
            W.PRODUCT_NUMBER, 
            ACQ.PRICE_USD 
         ) T 
       group by T.UID_WARE, 
          T.PRODUCT_NUMBER, 
          ACQ_PRICE_USD)) QTY 
    join WARES W on W.SUID = QTY.UID_WARE 
    join INVENTORY I on I.SUID = W.UID_ISSUE 
    join MAP_INFO MI on MI.SUID = I.SUID 
where REMAINS != 0 
     and w.UID_SECTION in ('MS-SEC-BOOKS', 'MS-SEC-MAPS')) 

回答

0

對於執行時間,從here

SQL> set timing on; 

在PL/SQL Developer,您可以獨立運行的每個子查詢 - 點擊鼠標,並按其標記F8。您將在SQL窗口的左下角看到執行時間(結果下方)。

Optimalization不是一件容易的事,你必須自己想 - 據我所知,沒有工具來爲你做這個。你的aproach可能取決於許多因素 - DB版本,底層操作系統,表大小,索引,...

你可以閱讀一些導遊(如thisthisthis

UPDATE

根據您的分貝版本,您可以嘗試使用CTESQL modelling - 它們會提高性能,但需要一些時間來學習。

代替group by,您可以嘗試analytic functions(例如partition by,例如參見this link)。

+0

我認爲這是F8不準確。因爲子查詢在我獨立執行時在500秒內獲取,當完整查詢進行80秒時。 – user1852786

+0

我只能使用項目和PL/SQL Developer,我還沒有訪問其他任何東西。 Ofcource我應該自己做,但我只想了解〜7選中的問題在哪裏,6'group by和5 join。我無法優化我不知道的東西。 – user1852786

+0

編輯你的問題併發布你的查詢,它會更容易幫助你。 – maialithar

1

當您使用GUI來分析和優化你把自己鎖在潛在援助的一個更小的社區查詢。如果您運行解釋計劃並使用DBMS_XPlan.Display來獲取格式化結果,那麼您正在使用由數萬名從業人員理解的標準方法。

而且,我懷疑你已經包裹在一個外部查詢查詢只COUNT(*)。儘管這可能會在沒有返回所有行的麻煩的情況下運行查詢,但您可能會得到完全不同的執行計劃,儘管有些提示可能有助於促進使用通常的計劃,但不能保證它能夠贏得「改變。所以,如果這是一個方便調整的方式,請把它拿走。

所以我的建議是:

  1. 運行解釋計劃的常規基於查詢的方式,不依賴於工具「幫助」。
  2. 運行您需要調整的實際查詢。
  3. 發佈執行計劃。