2011-08-06 34 views
1

讓我們來看看我遇到了很多問題。Oracle UPDATE性能問題和優化

表* CONF_ELEMENTI_FATTURABILI *大小爲160 Gb,並在2587個分區的edw_partition字段上進行分區(但並行性在第二個查詢中不起作用)。 * BCK_MEM_ANIMALI_F_ROPT_ELF *和* INT_TEMP51 *非常相似。他們有索引並且包含90k記錄(第二個是第一個的GROUP BY)。 更新基於PK。所以正好有90k條記錄被更新。

在30'以下更新查詢不會結束。我如何理解它是否正常工作。 並行執行不起作用(除一個以外的所有線程均空閒)。爲什麼?我應該強制一些完整的表/索引掃描嗎?

爲CONF_ELEMENTI_FATTURABILI其他詳情:
大小:161419,19 MB
區數:140964個
NUM_ROWS:2.62億(260億美元)
塊:10241238
進行分配YES - 2587個分區

第一種配方

alter session enable parallel dml; 

UPDATE 
    CONF_ELEMENTI_FATTURABILI elf 
    SET ELF_ELEMENTO_CHIUSO = 'C', 
     ELF_DATA_VER_FIN = 
      ( SELECT TELE_DATA_LETTURA 
       FROM NETATEMP.int_temp51 t 
       WHERE t.ELF_STORICO_ID = elf.ELF_STORICO_ID 
       AND t.edw_partition = elf.edw_partition) 
WHERE exists (SELECT 1 FROM netatemp.bck_mem_animali_f_ropt_elf kk WHERE kk.ELF_STORICO_ID = elf.ELF_STORICO_ID 
       AND kk.edw_partition = elf.edw_partition); 

解釋計劃:

Plan 
UPDATE STATEMENT ALL_ROWSCost: 87,99 Bytes: 6.269.021 Cardinality: 85,877     
    8 UPDATE SIUCONTRATTI.CONF_ELEMENTI_FATTURABILI    
     5 NESTED LOOPS Cost: 87,99 Bytes: 6.269.021 Cardinality: 85,877   
      2 SORT UNIQUE Cost: 67 Bytes: 1.975.171 Cardinality: 85,877  
       1 INDEX FAST FULL SCAN INDEX SIUINTEGRA.MEMBR_4 Cost: 67 Bytes: 1.975.171 Cardinality: 85,877 
      4 PARTITION LIST ITERATOR Cost: 2 Bytes: 50 Cardinality: 1 Partition #: 5 
       3 INDEX RANGE SCAN INDEX (UNIQUE) SIUCONTRATTI.CONF_ELF_UK_IDX1 Access Predicates: "KK"."ELF_STORICO_ID"="ELF"."ELF_STORICO_ID" AND "KK"."EDW_PARTITION"="ELF"."EDW_PARTITION" Cost: 2 Bytes: 50 Cardinality: 1 Partition #: 5 
     7 TABLE ACCESS BY INDEX ROWID TABLE SIUINTEGRA.INT_TEMP51 Cost: 69 Bytes: 256 Cardinality: 8   
      6 INDEX RANGE SCAN INDEX SIUINTEGRA.MEMBR_6 Access Predicates: "T"."ELF_STORICO_ID"=:B1 Cost: 2 Cardinality: 333  

第二製劑

UPDATE 
    CONF_ELEMENTI_FATTURABILI elf 
    SET ELF_ELEMENTO_CHIUSO = 'C', 
     ELF_DATA_VER_FIN = 
      ( SELECT TELE_DATA_LETTURA 
       FROM int_temp51 t 
       WHERE t.ELF_STORICO_ID = elf.ELF_STORICO_ID 
       AND t.edw_partition = elf.edw_partition) 
WHERE (ELF_STORICO_ID, edw_partition) IN (SELECT /*+ full(kk) parallel(kk, 20) */ ELF_STORICO_ID, edw_partition FROM bck_mem_animali_f_ropt_elf kk); 

解釋計劃:

Plan 
UPDATE STATEMENT ALL_ROWSCost: 7,168 Bytes: 6.269.021 Cardinality: 85,877          
    13 UPDATE SIUCONTRATTI.CONF_ELEMENTI_FATTURABILI         
     10 PX COORDINATOR       
      9 PX SEND QC (RANDOM) SYS.:TQ10001 Cost: 7,168 Bytes: 6.269.021 Cardinality: 85,877      
       8 NESTED LOOPS Cost: 7,168 Bytes: 6.269.021 Cardinality: 85,877      
        5 SORT UNIQUE Cost: 7 Bytes: 1.975.171 Cardinality: 85,877    
         4 PX RECEIVE Cost: 7 Bytes: 1.975.171 Cardinality: 85,877    
          3 PX SEND HASH SYS.:TQ10000 Cost: 7 Bytes: 1.975.171 Cardinality: 85,877   
           2 PX BLOCK ITERATOR Cost: 7 Bytes: 1.975.171 Cardinality: 85,877  
            1 TABLE ACCESS FULL TABLE SIUINTEGRA.BCK_MEM_ANIMALI_F_ROPT_ELF Cost: 7 Bytes: 1.975.171 Cardinality: 85,877 
        7 PARTITION LIST ITERATOR Cost: 2 Bytes: 50 Cardinality: 1 Partition #: 10     
         6 INDEX RANGE SCAN INDEX (UNIQUE) SIUCONTRATTI.CONF_ELF_UK_IDX1 Access Predicates: "ELF_STORICO_ID"="ELF_STORICO_ID" AND "EDW_PARTITION"="EDW_PARTITION" Cost: 2 Bytes: 50 Cardinality: 1 Partition #: 10   
     12 TABLE ACCESS BY INDEX ROWID TABLE SIUINTEGRA.INT_TEMP51 Cost: 69 Bytes: 256 Cardinality: 8        
      11 INDEX RANGE SCAN INDEX SIUINTEGRA.MEMBR_6 Access Predicates: "T"."ELF_STORICO_ID"=:B1 Cost: 2 Cardinality: 333       

就在線程的作品之一!

的等待:

ROWNUM SID EVENT       TOTAL_WAITS TOTAL_TIMEOUTS TIME_WAITED AVERAGE_WAIT MAX_WAIT TIME_WAITED_MICRO      
1  1012 latch: cache buffers chains    8    0   0   0   0    270  
2  1012 read by other session     366    0   141   0,38   3   1407428 
3  1012 db file sequential read    1287    0   772   0,6   4   7718838 
7  1012 events in waitclass Other    40    38   7613  190,33  195   76130586        
5  1012 PX Deq: Execution Msg     3    0   8   2,61   4    78312 
6  1012 PX Deq: Table Q Normal     2    0   1   0,34   1    6763 
4  1012 cursor: pin S wait on X     1    1   1   0,98   1    9829 
8  1114 latch: cache buffers chains    3    0   0   0   0     43  
9  1114 read by other session     381    0   131   0,34   4   1308282 
10  1114 db file sequential read    1416    0   841   0,59   4   8410582 
11  1114 cursor: pin S wait on X     1    1   1   0,98   1    9793 
12  1114 PX Deq: Execution Msg     3    0   8   2,65   4    79609 
13  1114 PX Deq: Table Q Normal     2    0   1   0,37   1    7441 
14  1114 events in waitclass Other    41    38   7576  184,78  195   75758618        
15  1154 latch: cache buffers chains    8    0   0   0   0    163  
16  1154 read by other session     368    0   141   0,38   3   1412020 
17  1154 db file sequential read    1819    0   1156   0,64   3   11555685        
18  1154 cursor: pin S wait on X     1    1   1   0,98   1    9833 
19  1154 PX Deq: Execution Msg     3    0   8   2,66   4    79754 
20  1154 PX Deq: Table Q Normal     2    0   1   0,36   1    7147 
21  1154 events in waitclass Other    38    35   7113  187,19  195   71130875        
22  1398 latch: cache buffers chains    4    0   0  

的IO

SID BLOCK_GETS CONSISTENT_GETS PHYSICAL_READS BLOCK_CHANGES CONSISTENT_CHANGES      
1012   0    9006   1805    0     0  
1114   0    9999   2393    0     0  
1154   0   10056   2668    0     0  
1398   0   10007   1917    0     0  
1597   0   10058   2046    0     0  
1649   0   10074   2261    0     0  
2279  92557   21996787  11908995   170829     206  
2322   0   10026   1863    0     0  
2460   0   10082   1927    0     0  
2479   0    9978   2006    0     0  
2694   0    9996   2462    0     0  
2800   0    8641   1767    0     0  
2829   0   10003   1855    0     0  
2840   0   10049   2280    0     0  
2888   0   10038   2574    0     0  
2998   0    9993   1995    0     0  
3147   0    8607   1569    0     0  
3186   0   10021   2478    0     0  
3219   0   10055   1773    0     0  
3227   0    9998   2678    0     0  
3228   0   10003   3083    0     0 

回答

3

儘管提供了大量的信息,我不知道有這裏真是夠有用的信息,以幫助回答這個問題,但我會放棄它。有一些關於表的關鍵字的信息以及你希望在這裏更新多少行將是有用的。

如果要更新的表有262M行和包含數據從更新表有90K的記錄,那麼你可以嘗試更新取決於按鍵之間的任何90K和262M行。

根據我的經驗,寫更新有點困難。它們從未像你想要的那樣被優化器處理。他們是更新行的少數或更新列在一個恆定值(SET ELF_ELEMENTO_CHIUSO = 'C'),但不那麼好聞,你需要另一個表中查找這些值高達有用。 SET子句中的子查詢似乎經常在表中的每一行都被調用。

出於這個原因,我通常會嘗試要麼寫MERGE陳述或UPDATE視圖。這兩種方法都有輕微的缺點,尤其是更新視圖,因爲需要注意許多限制條件,其中最重要的一點是它需要成爲保存鍵的表。這裏定義了一個保存表的關鍵字http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/views.htm#sthref3058

我認爲在這種情況下,當創建一個視圖時,您的表CONF_ELEMENTI_FATTURABILI應該被保留。所以更新視圖使用您的表的示例將是

UPDATE (
    select 
    elf.ELF_STORICO_ID, 
    elf.edw_partition, 
    elf.ELF_ELEMENTO_CHIUSO, 
    elf.ELF_DATA_VER_FIN, 
    t.TELE_DATA_LETTURA 
    from 
    CONF_ELEMENTI_FATTURABILI elf 
    join NETATEMP.int_temp51 t on (t.ELF_STORICO_ID = elf.ELF_STORICO_ID and 
            t.edw_partition = elf.edw_partition) 
) a 
set 
    a.ELF_ELEMENTO_CHIUSO = 'C', 
    a.ELF_DATA_VER_FIN = a.TELE_DATA_LETTURA; 

我不能保證這將工作,因爲關鍵的保存問題。它可能,或者它可能不會。即使這是我自己的數據,我也會遇到麻煩。

另一種選擇是MERGE聲明。這更有可能發揮作用,因爲它不依賴關鍵的保存,但我也有這個奇怪的問題。

合併的一個例子是:

MERGE INTO CONF_ELEMENTI_FATTURABILI elf 
USING NETATEMP.int_temp51 t on (t.ELF_STORICO_ID = elf.ELF_STORICO_ID and 
           t.edw_partition = elf.edw_partition) 
WHEN MATCHED THEN UPDATE SET elf.ELF_ELEMENTO_CHIUSO = 'C', 
          elf.ELF_DATA_VER_FIN = t.TELE_DATA_LETTURA 

正如我上面說的,我敢肯定,無論是上面所示的報表將實際工作,因爲他們都有點繁瑣並且是有原因的要麼失敗。希望你可以得到一些工作。

+0

非常感謝你,真是一個很好的答案! **另一個問題,爲什麼Parallelism不起作用?** – Revious

+0

我從來沒有在parallel中取得太多成功,但我認爲你還需要在'UPDATE'語句中添加並行提示。所以你需要'UPDATE/* + parallel(elf)*/CONF_ELEMENTI_FATTURABILI elf ...' –