我最近学习了DBMS的并行执行功能。我尝试用常规的update语句测试DBMS并行执行的性能。与常规的update语句相比,我没有看到性能上的改进。是不是少了点什么。附加示例代码details.The表由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秒。你能帮帮我吗?
发布于 2018-04-02 19:20:29
在创建任务和管理dbms_scheduler作业时肯定会有一定的开销,而且对于测试中极少的行数,普通的update需要做的工作更少。
我用一百万行进行了尝试,普通的update版本始终需要36秒才能完成,而dbms_parallel_execute版本的时间从36秒到9秒不等。(这是在我的笔记本电脑上,我并不期望从并行执行中获得太多好处。我的cpu_count = 2,parallel_threads_per_cpu = 2。我看到使用8个线程在6秒内完成。)
发布于 2018-04-02 16:34:57
因此,简单的非并行更新大约快9倍。更新似乎受到磁盘速度的限制,而不是CPU。我猜如果用SET e.NUM2 = some_heavy_calculation()代替SET e.NUM2 = 100,并行解决方案会更快。至少在计算足够重和CPU受限的情况下是这样。您的Oracle服务器也可以配置为不使用多个CPU内核。以数据库管理员(或用户system)身份运行show parameters,查看参数cpu_count和parallel_threads_per_cpu是否设置为1。或者检查旧的(?)CPU实际上只有一个内核。尝试将parallel_level=>5更改为NULL或2或其他数字。5个可能太多了。
https://stackoverflow.com/questions/49607401
复制相似问题