2011-09-16 80 views
1

我有以下查詢UPDATE查詢掛

UPDATE rec_analyst 
      SET analyst_name = (SELECT DISTINCT min (LIQA_ANALYST_LAST_NAME) 
           FROM LIQA 
           WHERE LIQA_ANALYST_ID = analyst_extern_id 
             AND LIQA_TS_INSERT = '15.09.2011' 

           ) 
     WHERE analyst_provider_id = 4 

解釋計劃顯示了4000左右的成本,但數據庫負荷爲100%,甚至一小時後這個工作還沒有準備好。 這裏解釋計劃輸出:

------------------------------------------------------------------------------------ 
DESC       |OBJECT NAME     |COST| # |BYTES | 
------------------------------------------------------------------------------------ 
UPDATE STATEMENT, GOAL =ALL_ROWS|        | 34| 16572| 331440| 
------------------------------------------------------------------------------------- 
    UPDATE      |REC_ANALYST     | |  |  | 
------------------------------------------------------------------------------------- 
    TABLE ACCESS FULL   |REC_ANALYST     | 34| 16572|331440 | 
------------------------------------------------------------------------------------- 
    SORT AGGREGATE    |        | |  |24  | 
------------------------------------------------------------------------------------- 
    TABLE ACCESS FULL   |REC_LIQA_LOAD_INQUIRY_ANALYST |3965|1  |24  | 
------------------------------------------------------------------------------------- 

我如何優化呢?

+2

你可以發佈解釋計劃嗎?什麼是索引列?順便說一句,你不需要DISTINCT,因爲你在子查詢中有MIN。如果LIQA_TS_INSERT是DATE字段,也可以使用TO_DATE和格式掩碼限定日期。 – Ollie

+0

你有關於LIQA_TS_INSERT的索引嗎?如果沒有,你會需要一個,假設你有一個數據。同樣在analyst_provider_id和LIQA_ANALYST_ID上。最好的事情是查看執行計劃並單獨嘗試查詢。 – TheCodeKing

+1

可能的問題:過期的數據庫統計信息(重新計算受影響表的統計信息並再試一次)或由其他會話中的併發更新導致的鎖定。 – Codo

回答

1

問問你的DBA,如果有可能/ advantagous添加以下的在任指數(最好是兩個):

表:rec_analyst柱:analyst_provider_id 表:LIQA列:LIQA_TS_INSERT

理想情況下,LIQA.analyst_id和rec_analyst.analyst_extern_id上存在PK/FK索引,但不知道您的模式是否很難說哪些索引會使整個系統受益。

5

你可以嘗試:

MERGE INTO rec_analyst ra 
USING (SELECT LIQA_ANALYST_ID analyst_id, MIN(LIQA_ANALYST_LAST_NAME) min_name 
      FROM LIQA 
     WHERE LIQA_TS_INSERT = '15.09.2011' 
     GROUP BY LIQA_ANALYST_ID 
    ) liqa_extract 
    ON (liqa_extract.analyst_id = ra.analyst_extern_id 
     AND ra.analyst_provider_id = 4 
    ) 
WHEN MATCHED THEN UPDATE SET ra.analyst_name = liqa_extract.min_name; 
+1

+1,因爲這也是我的確切答案。 –

+2

基本原理:通過這種方法,您可以防止執行liqa查詢的次數與使用provider_id 4的rec_analyst表中的行數相同。 –

+0

+1 Benoit,很好地使用MERGE。 – Ollie