Exadata 上的 Oracle 数据库。更新运行数小时,并行提示不起作用

标签 oracle performance parallel-processing updates exadata

我们有两个巨大的表并试图更新大约 6000 万条记录。以前是30分钟更新一次,现在是几个小时n个小时,连20%的数据增长都没有。这里有更多信息。我看到在“单元格单 block 物理读取”“PX Deq:表 Q 正常”事件上有很多等待。我不明白为什么并行提示不起作用。这是单元格单 block 物理读取的原因吗?还是有任何其他原因导致性能下降,任何想法 ?以及为什么要通过删除“WHERE EXISTS”子句来提高性能?

表 1(A) 大小 316 GB 记录数 456,365,654

表 2(B) 7GB 记录数 31,934,956

   UPDATE /*+  parallel (a, 8) */
          table1 a
       SET (c_age,
            c_age_de,
            wa_only_ind) =
              (SELECT c_age,
                      c_age_de,
                      wa_only_ind
                 FROM table2 b
                WHERE     B.ip = A.ip
                      AND a.c_age IS NULL
                      AND b.o_type IN ('TYPE12', 'TYPE14'))
     WHERE EXISTS
              (SELECT 1
                 FROM table2 b2
                WHERE     b2.ip = a.ip
                      AND a.c_age IS NULL
                      AND b2.o_type IN ('TYPE12', 'TYPE14'));

解释计划

   ----------------------------------------------------------------------------------------------------------------------------------------------------------
    | Id  | Operation                        | Name                    | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
    ----------------------------------------------------------------------------------------------------------------------------------------------------------
    |   0 | UPDATE STATEMENT                 |                         |     17M|  9599M|  5076M (20)|999:59:59 |       |       |        |      |            |
    |   1 |  UPDATE                          | TABLE1                  |        |       |            |          |       |       |        |      |            |
    |   2 |   PX COORDINATOR                 |                         |        |       |            |          |       |       |        |      |            |
    |   3 |    PX SEND QC (RANDOM)           | :TQ10002                |     17M|  9599M|  1069K  (1)| 04:09:40 |       |       |  Q1,02 | P->S | QC (RAND)  |
    |*  4 |     HASH JOIN RIGHT SEMI BUFFERED|                         |     17M|  9599M|  1069K  (1)| 04:09:40 |       |       |  Q1,02 | PCWP |            |
    |   5 |      PX RECEIVE                  |                         |     29M|   476M| 23984   (2)| 00:05:36 |       |       |  Q1,02 | PCWP |            |
    |   6 |       PX SEND HASH               | :TQ10000                |     29M|   476M| 23984   (2)| 00:05:36 |       |       |  Q1,00 | P->P | HASH       |
    |   7 |        PX BLOCK ITERATOR         |                         |     29M|   476M| 23984   (2)| 00:05:36 |       |       |  Q1,00 | PCWC |            |
    |*  8 |         TABLE ACCESS STORAGE FULL| TABLE2                  |     29M|   476M| 23984   (2)| 00:05:36 |       |       |  Q1,00 | PCWP |            |
    |   9 |      PX RECEIVE                  |                         |     57M|    30G|  1045K  (1)| 04:04:04 |       |       |  Q1,02 | PCWP |            |
    |  10 |       PX SEND HASH               | :TQ10001                |     57M|    30G|  1045K  (1)| 04:04:04 |       |       |  Q1,01 | P->P | HASH       |
    |  11 |        PX BLOCK ITERATOR         |                         |     57M|    30G|  1045K  (1)| 04:04:04 |     1 |     3 |  Q1,01 | PCWC |            |
    |* 12 |         TABLE ACCESS STORAGE FULL| TABLE1                  |     57M|    30G|  1045K  (1)| 04:04:04 |     1 |     6 |  Q1,01 | PCWP |            |
    |* 13 |   FILTER                         |                         |        |       |            |          |       |       |        |      |            |
    |* 14 |    TABLE ACCESS BY INDEX ROWID   | TABLE2                  |      1 |   210 |     4   (0)| 00:00:01 |       |       |        |      |            |
    |* 15 |     INDEX RANGE SCAN             | TABLE2_IDX1             |      1 |       |     3   (0)| 00:00:01 |       |       |        |      |            |
    ----------------------------------------------------------------------------------------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("B2"."IP"="A"."IP")
   8 - storage("B2"."O_TYPE"='TYPE1' OR "B2"."O_TYPE"='TYPE12')
       filter("B2"."O_TYPE"='TYPE1' OR "B2"."O_TYPE"='TYPE12')
  12 - storage("A"."C_AGE" IS NULL)
       filter("A"."C_AGE" IS NULL)
  13 - filter(:B1 IS NULL)
  14 - filter("B"."O_TYPE"='TYPE1' OR "B"."O_TYPE"='TYPE12')
  15 - access("B"."IP"=:B1)


 SQL_ID  dd0ah20057j37
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                        | Name                         | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |  OMem |  1Mem |  O/1/M   |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT                 |                              |        |       |    43T(100)|          |       |       |        |      |            |       |       |          |
|   1 |  UPDATE                          | TABLE1                   |        |       |            |          |       |       |        |      |            |       |       |          |
|   2 |   PX COORDINATOR                 |                              |        |       |            |          |       |       |        |      |            |       |       |          |
|   3 |    PX SEND QC (RANDOM)           | :TQ10002                     |     57M|    31G| 65326   (3)| 00:14:16 |       |       |  Q1,02 | P->S | QC (RAND)  |       |       |          |
|*  4 |     HASH JOIN RIGHT SEMI BUFFERED|                              |     57M|    31G| 65326   (3)| 00:14:16 |       |       |  Q1,02 | PCWP |            |  1537M|    25M|     2/0/0|
|   5 |      PX RECEIVE                  |                              |     32M|   550M|  2190  (20)| 00:00:29 |       |       |  Q1,02 | PCWP |            |       |       |          |
|   6 |       PX SEND HASH               | :TQ10000                     |     32M|   550M|  2190  (20)| 00:00:29 |       |       |  Q1,00 | P->P | HASH       |       |       |          |
|   7 |        PX BLOCK ITERATOR         |                              |     32M|   550M|  2190  (20)| 00:00:29 |       |       |  Q1,00 | PCWC |            |       |       |          |
|*  8 |         TABLE ACCESS STORAGE FULL| TABLE2 P1      |     32M|   550M|  2190  (20)| 00:00:29 |       |       |  Q1,00 | PCWP |            |  1025K|  1025K|     2/0/0|
|   9 |      PX RECEIVE                  |                              |     57M|    30G| 63100   (2)| 00:13:47 |       |       |  Q1,02 | PCWP |            |       |       |          |
|  10 |       PX SEND HASH               | :TQ10001                     |     57M|    30G| 63100   (2)| 00:13:47 |       |       |  Q1,01 | P->P | HASH       |       |       |          |
|  11 |        PX BLOCK ITERATOR         |                              |     57M|    30G| 63100   (2)| 00:13:47 |     1 |     3 |  Q1,01 | PCWC |            |       |       |          |
|* 12 |         TABLE ACCESS STORAGE FULL| TABLE1                   |     57M|    30G| 63100   (2)| 00:13:47 |     1 |     6 |  Q1,01 | PCWP |            |  1025K|  1025K|     2/0/0|
|* 13 |   FILTER                         |                              |        |       |            |          |       |       |        |      |            |       |       |          |
|* 14 |    TABLE ACCESS BY INDEX ROWID   | TABLE2          |    320K|   113M| 12787   (1)| 00:02:48 |       |       |        |      |            |       |       |          |
|* 15 |     INDEX RANGE SCAN             | TABLE2_IDX1          |    128K|       |     4  (25)| 00:00:01 |       |       |        |      |            |  1025K|  1025K|          |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("U2"."IP"="I"."IP")
   8 - storage(:Z>=:Z AND :Z<=:Z AND (("U2"."OPERATION_TYPE"='TYPE1' OR "U2"."OPERATION_TYPE"='TYPE12')))
       filter(("U2"."OPERATION_TYPE"='TYPE1' OR "U2"."OPERATION_TYPE"='TYPE12'))
  12 - storage(:Z>=:Z AND :Z<=:Z AND "I"."AGE" IS NULL)
       filter("I"."AGE" IS NULL)
  13 - filter(:B1 IS NULL)
  14 - filter(("U"."OPERATION_TYPE"='TYPE1' OR "U"."OPERATION_TYPE"='TYPE12'))
  15 - access("U"."IP"=:B1)

Plan hash value: 1669240984

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                    | E-Rows |E-Bytes|E-Temp | Cost (%CPU)| E-Time   | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |  OMem |  1Mem |  O/1/M   |
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|   0 | MERGE STATEMENT                   |                         |        |       |       |   374K(100)|          |       |       |        |      |            |       |       |          |
|   1 |  MERGE                            | TABLE1                    |        |       |       |            |          |       |       |        |      |            |       |       |          |
|   2 |   PX COORDINATOR                  |                         |        |       |       |            |          |       |       |        |      |            |       |       |          |
|   3 |    PX SEND QC (RANDOM)            | :TQ10002                |    413M|   574G|       |   374K  (2)| 01:21:50 |       |       |  Q1,02 | P->S | QC (RAND)  |       |       |          |
|   4 |     VIEW                          |                         |        |       |       |            |          |       |       |  Q1,02 | PCWP |            |       |       |          |
|*  5 |      HASH JOIN BUFFERED           |                         |    413M|   574G|  3583M|   374K  (2)| 01:21:50 |       |       |  Q1,02 | PCWP |            |  2047M|   100M|          |
|   6 |       PX RECEIVE                  |                         |     32M|    27G|       |  2199  (20)| 00:00:29 |       |       |  Q1,02 | PCWP |            |       |       |          |
|   7 |        PX SEND HASH               | :TQ10000                |     32M|    27G|       |  2199  (20)| 00:00:29 |       |       |  Q1,00 | P->P | HASH       |       |       |          |
|   8 |         PX BLOCK ITERATOR         |                         |     32M|    27G|       |  2199  (20)| 00:00:29 |       |       |  Q1,00 | PCWC |            |       |       |          |
|*  9 |          TABLE ACCESS STORAGE FULL| TABLE2           |     32M|    27G|       |  2199  (20)| 00:00:29 |       |       |  Q1,00 | PCWP |            |  1025K|  1025K|     2/0/0|
|  10 |       PX RECEIVE                  |                         |    413M|   218G|       | 67413   (9)| 00:14:44 |       |       |  Q1,02 | PCWP |            |       |       |          |
|  11 |        PX SEND HASH               | :TQ10001                |    413M|   218G|       | 67413   (9)| 00:14:44 |       |       |  Q1,01 | P->P | HASH       |       |       |          |
|  12 |         PX BLOCK ITERATOR         |                         |    413M|   218G|       | 67413   (9)| 00:14:44 |     1 |     3 |  Q1,01 | PCWC |            |       |       |          |
|* 13 |          TABLE ACCESS STORAGE FULL| TABLE1              |    413M|   218G|       | 67413   (9)| 00:14:44 |     1 |     6 |  Q1,01 | PCWP |            |  1025K|  1025K|     2/0/0|
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   5 - access("I"."IP"="U"."IP")
   9 - storage(:Z>=:Z AND :Z<=:Z AND (("U"."OPERATION_TYPE"='TYPE1' OR "U"."OPERATION_TYPE"='TYPE12')))
       filter(("U"."OPERATION_TYPE"='TYPE1' OR "U"."OPERATION_TYPE"='TYPE12'))
  13 - storage(:Z>=:Z AND :Z<=:Z)

最佳答案

  1. alter session enable parallel dml; 当前计划只有部分并行运行。 UPDATE 操作应该低于 PX COORDINATOR 操作,而不是高于它。这可能是因为 session 没有启用并行 DML。

下面是一个示例模式和查询,展示了在启用 session 并行性时计划如何变化。

drop table test1 purge;
create table test1(a number not null, b number);
insert into test1 select level, 1 from dual connect by level <= 100000;
begin
    dbms_stats.gather_table_stats(user, 'TEST1');
end;
/

alter session disable parallel dml;
explain plan for update /*+ parallel(test1, 8) */ test1 set a = 1 where b <= 1000;
select * from table(dbms_xplan.display);

---------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |          |   100K|   781K|    11  (10)| 00:00:01 |        |      |            |
|   1 |  UPDATE               | TEST1    |       |       |            |          |        |      |            |
|   2 |   PX COORDINATOR      |          |       |       |            |          |        |      |            |
...

rollback;
alter session enable parallel dml;
explain plan for update /*+ parallel(test1, 8) */ test1 set a = 1 where b <= 1000;
select * from table(dbms_xplan.display);


---------------------------------------------------------------------------------------------------------------
| Id  | Operation             | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT      |          |   100K|   781K|    11  (10)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR       |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM) | :TQ10000 |   100K|   781K|    11  (10)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    UPDATE             | TEST1    |       |       |            |          |  Q1,00 | PCWP |            |
...
  1. MERGE 您的评论说您已经尝试过 MERGE,但结合其他提示可能值得再试一次。 MERGE 允许 TABLE2 仅列出一次,从而移除连接。并且MERGE支持比UPDATE更多的join方法,例如修改后的表和其他行源之间的hash join。
  2. 语句级并行提示。自 11gR2 起,对象几乎不应该列在并行提示中。当未列出对象时,提示适用于整个语句。如果在语句的一部分中使用了并行性,那么在所有地方使用它几乎没有坏处。将 /*+ parallel (a, 8) */ 替换为 /*+ parallel (8) */
  3. 发生了什么变化?即使上述提示有所帮助,了解发生变化并导致性能问题的原因仍然是一件好事。如果计划发生变化,则应在 AWR 中捕获不同的计划。使用以下语句查找它们:select * from table(dbms_xplan.display_awr(sql_id => 'Your SQL_ID')); 仅有计划是不够的,尤其是在数据仓库中。可能需要通过在操作级别聚合等待事件来比较运行。所有信息都在 DBA_HIST_ACTIVE_SESS_HISTORY 中,但需要自定义查询。

关于Exadata 上的 Oracle 数据库。更新运行数小时,并行提示不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25774143/

相关文章:

linux - 如果 linux 中的任何 PID 超过某个限制,如何发出警报?

java - 在 Java 中缩放数组的最有效方法?

loops - 关于MPI并行循环的问题

.net - 我是否需要安装任何额外的库才能在 Mono 上运行的 F# 中使用 Array.Parallel.map?

oracle - 编译oracle表格

linux - 从 cronjob 运行脚本时,pl/sql 部分不执行

sql - 使用动态创建的字符串向用户授予角色

performance - DoNotCastUnnecessarily真的是性能规则吗?

Java - 如何使用自定义类型调用 oracle 过程?

c++ - 在允许并行性的情况下用 STL 算法替换 for 循环