我最近学习了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秒。你能帮我解决这个问题。
答案 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_count
和parallel_threads_per_cpu
是否设置为1.或者检查您的旧(?)CPU是否实际上只是有一个内核。尝试将parallel_level=>5
更改为NULL
或2
或其他一些号码。 5可能太多了。