定期更新与DBMS并行执行

时间:2018-04-02 07:52:09

标签: sql oracle plsql

我最近学习了DBMS并行执行功能。我尝试使用常规更新语句测试DBMS并行执行的性能。我没有看到相对于常规更新语句的性能改进。有什么东西丢失了。附加示例代码详细信息。该表包含7,020行。

DECLARE
  l_sql_stmt VARCHAR2(1000);
  l_try      NUMBER;
  l_status   NUMBER;
BEGIN
  -- Create the TASK
  DBMS_PARALLEL_EXECUTE.CREATE_TASK ('mytask');
  -- Chunk the table by ROWID
  DBMS_PARALLEL_EXECUTE.CREATE_CHUNKS_BY_ROWID('mytask', 'REVPRO_1001', 'RPRO_RC_LINE_G', true, 1000);
  -- Execute the DML in parallel
  l_sql_stmt := 'update /*+ ROWID (dda) */ RPRO_RC_LINE_G e       
                  SET e.NUM2 = 100    
                  WHERE rowid BETWEEN :start_id AND :end_id';

  DBMS_PARALLEL_EXECUTE.RUN_TASK('mytask', l_sql_stmt, DBMS_SQL.NATIVE, parallel_level => 5);
  -- If there is an error, RESUME it for at most 2 times.
  L_try      := 0;
  L_status   := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
  DBMS_OUTPUT.PUT_LINE('Status'||L_status);
  WHILE(l_try < 2 AND L_status != DBMS_PARALLEL_EXECUTE.FINISHED)
  LOOP
    L_try := l_try + 1;
    DBMS_PARALLEL_EXECUTE.RESUME_TASK('mytask');
    L_status := DBMS_PARALLEL_EXECUTE.TASK_STATUS('mytask');
  END LOOP;
  -- Done with processing; drop the task
  DBMS_PARALLEL_EXECUTE.DROP_TASK('mytask');
END;

上述块需要经过时间:00:00:03.315来更新表格。

BEGIN
  UPDATE /*+ ROWID (dda) */
    RPRO_RC_LINE_G e SET e.NUM2 = 100 ;
END;

当我使用简单的SQL查询更新同一个表时,它需要经过的时间00:00:00.370。

比DBMS并行执行快3秒。你能帮我解决这个问题。

2 个答案:

答案 0 :(得分:2)

创建任务和管理dbms_scheduler作业肯定会有一定的开销,而对于测试中的少量行,普通update的工作量较少。

我尝试了一百万行,普通update持续36秒完成,而dbms_parallel_execute版本从36秒到9秒不等。 (这是在我的笔记本电脑上,我并不期望从并行执行获得太多收益。我的cpu_count = 2,parallel_threads_per_cpu = 2.我看到使用8个线程在6秒内完成。)

答案 1 :(得分:0)

因此,简单的非并行更新速度提高了大约9倍。好像更新受磁盘速度限制,而不是CPU。我猜测SET e.NUM2 = 100而不是SET e.NUM2 = some_heavy_calculation()并行解决方案会更快。至少如果计算足够重且受CPU限制。您的Oracle服务器也可以配置为不利用多个CPU内核。以DBA(或用户show parameters)运行system以查看参数cpu_countparallel_threads_per_cpu是否设置为1.或者检查您的旧(?)CPU是否实际上只是有一个内核。尝试将parallel_level=>5更改为NULL2或其他一些号码。 5可能太多了。