2011-01-06 107 views
0

夥計們,我有以下的Oracle SQL查詢,給我的日期之間的月份報告。基本上,nov月我想要的日期之間01nov到30 nov之間的值的總和。 正在查詢的表位於另一個數據庫中,並使用dblink訪問。 DT列是NUMBER類型的(例如20101201)。甲骨文SQL查詢需要一天的時間返回結果使用dblink

SELECT /*+ PARALLEL (A 8) */ /*+ DRIVING_STATE(A) */ 
TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')- 1,'MM'),'MONYYYY') "MONTH", 
    TYPE AS "TYPE", COLUMN, COUNT (DISTINCT A) AS "A_COUNT", 
    COUNT (COLUMN) AS NO_OF_COLS, SUM (DURATION) AS "SUM_DURATION", 
    SUM (COST) AS "COST" FROM **[email protected]_PROD A** 
     WHERE DT >= TO_NUMBER(TO_CHAR(add_months(SYSDATE,-1),'YYYYMM"01"')) 
     AND DT < TO_NUMBER(TO_CHAR(SYSDATE,'YYYYMM"01"')) 
     GROUP BY TYPE, COLUMN 

查詢的執行需要一整天的時間並且沒有完成。好心建議我,如果他們是可以建議我的數據庫管理員在dblink上的任何優化,或任何可以在查詢上完成的調整,或重寫相同。

地更新其表

該表partiontioned日期列和近十億的記錄。

下面我給出的TOAD EXPLAIN PLAN

**Plan** 
SELECT STATEMENT REMOTE ALL_ROWSCost: 1,208,299 Bytes: 34,760 Cardinality: 790            
    12 PX COORDINATOR           
     11 PX SEND QC (RANDOM) SYS.:TQ10002 Cost: 1,208,299 Bytes: 34,760 Cardinality: 790           
      10 SORT GROUP BY Cost: 1,208,299 Bytes: 34,760 Cardinality: 790          
       9 PX RECEIVE Cost: 1,208,299 Bytes: 34,760 Cardinality: 790         
        8 PX SEND HASH SYS.:TQ10001 Cost: 1,208,299 Bytes: 34,760 Cardinality: 790        
         7 SORT GROUP BY Cost: 1,208,299 Bytes: 34,760 Cardinality: 790      
          6 PX RECEIVE Cost: 1,208,299 Bytes: 34,760 Cardinality: 790      
           5 PX SEND HASH SYS.:TQ10000 Cost: 1,208,299 Bytes: 34,760 Cardinality: 790     
            4 SORT GROUP BY Cost: 1,208,299 Bytes: 34,760 Cardinality: 790   
             3 FILTER   
              2 PX BLOCK ITERATOR Cost: 1,203,067 Bytes: 15,066,833,144 Cardinality: 342,428,026 Partition #: 11 Partitions accessed #1 - #5 
               1 TABLE ACCESS FULL TABLE CDRR.FRD_CDF_DATA_INTL_IN_P Cost: 1,203,067 Bytes: 15,066,833,144 Cardinality: 342,428,026 Partition #: 11 

下面的事情我今天做的,任何額外的提示,將是有益的。

  1. 我要收集此表,這可能會給最佳 執行計劃的tablewise統計。
  2. 檢查是否爲該分區創建了本地索引。
  3. 使用BETWEEN而不是> =和<。
+2

只是好奇,多久沒有考慮到遠程數據庫上直接運行?如果查詢本身花費很長時間,那麼數據庫鏈接可能是一條紅鯡魚。 – 2011-01-06 13:44:24

+0

10億行!難怪需要很長時間!網絡速度不錯 – 2011-01-06 13:49:16

回答

1

像往常一樣,這種類型的問題,解釋計劃將是有用的。這將有助於我們確定數據庫中實際發生的情況。

理想情況下,您希望確保查詢在遠程數據庫上運行,而不是通過鏈接發送數據並在本地運行查詢。這可確保通過鏈接發送更少的數據。 DRIVING_SITE提示可以幫助解決這個問題,儘管Oracle通常相當聰明,所以它可能根本沒有幫助。

Oracle似乎在運行遠程查詢方面做得更好,但仍然存在問題。

此外,它可能會支付簡化您的一些日期轉換。

例如,更換此:

TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')- 1,'MM'),'MONYYYY') 

與此:

TO_CHAR(add_months(TRUNC(SYSDATE,'MM'), -1),'MONYYYY') 

這可能會更有效,也更容易閱讀。

同樣替換此:

WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD')) 
    AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD')) 

WHERE DT >=TO_NUMBER(TO_CHAR(add_months(TRUNC(SYSDATE,'MM'), -1),'YYYYMMDD')) 
    AND DT < TO_NUMBER(TO_CHAR(TRUNC(SYSDATE,'MM'),'YYYYMMDD')) 

甚至

WHERE DT >=TO_NUMBER(TO_CHAR(add_months(SYSDATE,-1),'YYYYMM"01"')) 
    AND DT < TO_NUMBER(TO_CHAR(SYSDATE,'YYYYMM"01"')) 
1

如果不知道表結構,約束條件,索引,數據量,結果集大小,網絡速度,併發水平,執行計劃等等,就無法回答。

有些事情,我會調查:

如果表被分區,併爲查詢打到分區存在統計?一個常見的問題是,在插入數據之前,統計信息會在空分區上收集。然後,當您查詢它時(在刷新統計信息之前),Oracle選擇索引掃描,實際上它應該在該分區上使用FTS。

而且相關統計:確保

WHERE DT >=TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM')-1,'MM'),'YYYYMMDD')) 
    AND DT < TO_NUMBER(TO_CHAR(TRUNC(TRUNC(SYSDATE,'MM'),'MM'),'YYYYMMDD')) 

生成相同的執行計劃爲:

WHERE DT >= 20101201 
    AND DT < 20110101 

更新 什麼版本的Oracle是你嗎?我問的原因是,在Oracle 10g及更高版本中,在這種情況下應該已經選擇了另一個組的實現(散列而不是排序)。它看起來基本上是對日期過濾器(14千兆字節)返回的3.42億行進行排序。你有RAM來支持它嗎?否則,你會做一個多通道排序,溢出到磁盤。這可能是發生了什麼事情。

根據計劃,將返回約790行。那是在正確的場地嗎? 如果是這樣,你可以排除網絡問題:)

此外,我不完全熟悉該計劃的格式。表子是否分區?否則,我不會得到分區#11的參考。