Проблема производительности и обновления Oracle UPDATE - PullRequest
1 голос
/ 06 августа 2011

Давайте возьмем запрос, с которым у меня было много проблем.

Таблица * CONF_ELEMENTI_FATTURABILI * имеет размер 160 Гб и разделена на поле edw_partition в 2587 разделах (но параллелизм не работает во втором запросе)).* BCK_MEM_ANIMALI_F_ROPT_ELF * и * INT_TEMP51 * очень похожи.Они имеют индексы и содержат 90 тыс. Записей (вторая - это GROUP BY первой).Обновление основано на ПК.Таким образом, обновляется ровно 90 тысяч записей.

Через 30 минут следующий запрос на обновление не заканчивается.Как я могу понять, работает ли это или нет. Параллельное выполнение не работает (все потоки, кроме одного, были простаивающими).Почему? Должен ли я принудительно выполнить полное сканирование таблицы / индекса?

Другие сведения для CONF_ELEMENTI_FATTURABILI:
Размер: 161419,19 МБ
Число Экстенты: 140964
NUM_ROWS: 262000000 (260миллион)
БЛОКИ: 10241238
РАЗДЕЛЕНО: ДА - 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  

1 Ответ

3 голосов
/ 06 августа 2011

Несмотря на то, что я предоставил много информации, я не уверен, что здесь действительно достаточно полезной информации, чтобы помочь с ответом на этот вопрос, но я попробую.Было бы полезно получить некоторую информацию о ключах таблиц, а также о том, сколько строк вы ожидаете обновить здесь.

Если в обновляемой таблице 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

Как я уже сказал выше, я уверен, что любое из приведенных выше утверждений действительно сработает, потому что они оба немного неудобны, и есть причины, по которым любое из них может потерпеть неудачу.Надеюсь, вы можете получить что-то работающее, хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...