在Oracle 11g R2以及之前的版本,你的SQL执行可能被延迟,直到有充足的并行服务器可用。
Oracle有一种轮换IO机制,叫做“直接路径IO”,如果它判断到绕过缓存区直接执行IO会更快速的话, 它就会启用。例如,Oracle在读写临时段进行排序或者整理中间结果集时就会使用直接IO。从Oracle 11g开始,Oracle有时也优先利用直接路径IO来处理串行表访问,而不是正常的缓存IO。
在执行并行查询操作时,Oracle通常会使用直接路径IO。通过使用直接路径IO,Oracle可以避免创建高速缓存竞争,并可以使IO更加优化地在并行进程之间分配。此外,对于执行全表扫描的并行操作,在高速缓存找到匹配数据的机会相当低,因此高速缓存几乎没有增加什么价值。
在Oracle 10g以及更早的版本,并行查询总是使用直接路径IO,而串行查询将总是使用缓存IO。在11g中,Oracle可以对并行查询利用缓存IO(从11g R2以后的版本支持),而且串行查询也可能利用直接路径IO。然而,并行查询仍然不太可能利用缓存IO,因此,可能比串行查询需要更高的IO成本。当然, 更高的IO成本将在所有并行进程之间共享,这样整体性能仍可能更胜一筹。
并行的优化准则
从优化串行执行的SQL开始
一个最理想的并行计划与最佳的串行计划可能是有区别的。例如,并行处理通常从表或索引的扫描开始,而最佳串行计划可能是基于索引查找开始。然而,你应该确保你的查询在进行并行优化之前先对串行执行进行优化,原因如下:
1、串行调试的结构和方法主要针对索引和统计集合,而这些经常对好的并行调试也非常关键。
2、如果请求并行执行的资源不可用,你的查询可能被串行化(这取决于“PARALLEL_DEGREE_ POLICY”和“PARALLEL_MIN_PERCENT”的设置)。在这种情况下,你要确保你并行查询的串行计划足够好。
缺少调优的SQL甚至可能变成更差的SQL,至少考虑到对其他用户的影响时是这样,这使它被允许消耗数据库服务器更多的CPU和IO资源。
在为并行执行优化SQL语句时,要从未串行执行SQL优化开始。
确保该SQL是合适的并行执行SQL
不是每个SQL都能从并行执行中获益的。下面是一些例子,这些情况的SQL语句可能不应该被并行化。
1、串行执行时,执行时间很短的SQL语句。
2、可能在多个会话中高并发率运行的SQL语句。
3、基于索引查找的SQL语句。非并行的索引查找或者范围扫描不能被并行化。然而,索引全扫描可以被并行化。在分区索引上的索引查找也可以被并行化。
综上3点,OLTP类型的查询通常不适合并行化处理。
确保系统适合配置为并行执行
不是所有的SQL都适合并行执行,也不是所有的数据库服务器主机适合配置并行处理。在当今世界,大部分物理服务器主机都满足如下最小需求:多块CPU和 跨多个物理驱动器的数据带。然而,一些虚拟主机可能不满足这些最小需求,而桌面计算机通常只有唯一的磁盘设备,因此通常不适合调整为并行执行。
不要尝试在那些不满足最小需求(多块CPU和跨多个磁盘驱动器的数据带)的计算机系统上使用并行执行。
确保执行计划的所有部分都被并行化了
在复杂的并行SQL语句中,很重要的一点是要确保该查询执行的所有重要步骤都实现了并行。如果某复杂查询的其中一个步骤是串行执行的,其他并行步骤可能 也不得不等待该串行步骤完成,这样并行机制的优势就完全丧失了。“PLAN_TABLE”表中的“OTHER_TAG”列用 “PARALLEL_FROM_SERIAL”标记指定了这样一个步骤,“DBMS_XPLAN”在“IN-OUT”列中记录了“S->P”。例如:在下面的例子中表“T1”是并行化的,但是表“T”不是。对两个表的连接和“GROUP BY”包括许多并行操作,但是对“T”表的全表扫描不是并行化的,串到并(S->P)标记展示了“t”行被串行提取到后续并行操作中:
SQL> ALTER TABLE customers PARALLEL(DEGREE 4);
SQL> ALTER TABLE sales NOPARALLEL ;
SQL> explain plan for select /*+ ordered use_hash(t1) */ t.name,sum(t.id) from t,t1 where t.id=t1.object_id group by t.name;
SQL> 1* select * from table(dbms_xplan.display)
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 2575143521
----------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 61 | 4758 | 22 (10)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10002 | 61 | 4758 | 22 (10)| 00:00:01 | Q1,02 | P->S | QC (RAND) |
| 3 | HASH GROUP BY | | 61 | 4758 | 22 (10)| 00:00:01 | Q1,02 | PCWP | |
| 4 | PX RECEIVE | | 61 | 4758 | 22 (10)| 00:00:01 | Q1,02 | PCWP | |
| 5 | PX SEND HASH | :TQ10001 | 61 | 4758 | 22 (10)| 00:00:01 | Q1,01 | P->P | HASH |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 6 | HASH GROUP BY | | 61 | 4758 | 22 (10)| 00:00:01 | Q1,01 | PCWP | |
|* 7 | HASH JOIN | | 61 | 4758 | 21 (5)| 00:00:01 | Q1,01 | PCWP | |
| 8 | BUFFER SORT | | | | | | Q1,01 | PCWC | |
| 9 | PX RECEIVE | | 61 | 3965 | 12 (0)| 00:00:01 | Q1,01 | PCWP | |
| 10 | PX SEND BROADCAST | :TQ10000 | 61 | 3965 | 12 (0)| 00:00:01 | | S->P | BROADCAST |
| 11 | TABLE ACCESS FULL | T | 61 | 3965 | 12 (0)| 00:00:01 | | | |
| 12 | PX BLOCK ITERATOR | | 52078 | 661K| 8 (0)| 00:00:01 | Q1,01 | PCWC | |
| 13 | INDEX FAST FULL SCAN| T1_IDX | 52078 | 661K| 8 (0)| 00:00:01 | Q1,01 | PCWP | |
----------------------------------------------------------------------------------------------------------------------
像前面这种情况,部分并行化执行计划可能会导致两方面效果都很差:消耗的时间并没有改善,因为串行操作形成了整个执行的瓶颈。然而,该SQL还捆绑了并行服务器进程,而且可能影响其他并发执行SQL的性能。
如果我们为表“t”设置一个默认的并行度,该串行瓶颈将会消失。对“t”表的全扫描现在是按并行执行了,而且“串到并S->P”瓶颈将被全并行的“并到并P->P”操作替代
在优化并行执行计划时,要确保所有相关步骤都在并行执行:“DBMS_XPLAN”中的串到并S->P 标记或者“PLAN_TABLE”中的“PARALLEL_FROM_SERIAL”通常指示在并行计划的某些方面存在串行瓶颈。
确保请求的DOP(Degree Of Parallel)是可实现的
超过调优限度增加DOP可能给系统增加额外负载,而不会提升性能。在最坏的情况下,超过调优限度增加DOP可以导致查询运行时间减少。因此,设置合适的DOP对于数据库整体的健康和并行查询的性能优化都是非常重要的。
确保你请求或预期的DOP是现实的;过高的DOP可以导致数据库服务器负载过度,而不会提升SQL的性能。
监视实际DOP
你请求的DOP可能被优化,但是并不总是能成功。当多个并行查询竞争有限的并行执行资源时,DOP可能会减少,或者SQL语句可能会以串行模式运行。
我们前面讨论了Oracle如何决定实际DOP;最重要的参数“PARALLEL_MIN_PERCENT”,“PARALLEL_DEGREE_ POLICY”和“PARALLEL_ADAPTIVE_MULTI_USER”控制了Oracle改变DOP的方式,不管语句运行在降低并行,出错终止,还是在现存资源不足以请求的DOP运行该语句时推迟到后续处理。
DOP的减少可以导致你的并行SQL表现出令人失望的性能。你应该监视查询执行来看是否DOP的减少确实出现了。我们可以使用“V$PQ_TQSTAT”来度量实际DOP。见下例,
SQL> select dfo_number,tq_id,server_type,min(num_rows),max(num_rows),count(*) dop
from v$pq_tqstat
group by dfo_number,tq_id,server_type
order by dfo_number,tq_id,server_type
2 3 4 5 ;
DFO_NUMBER TQ_ID SERVER_TYPE MIN(NUM_ROWS) MAX(NUM_ROWS) DOP
---------- ---------- ------------------------------ ------------- ------------- ----------
1 0 Consumer 61 61 1
1 0 Producer 0 49 4
值得一提的是,由于操作间并行会有多组slave process通信,例如组1scan数据给组2 order by, 该视图中的server_type字段中就把 组1定义为生产者(producer),组2定义为消费者(consumer)
我们还可以利用v$session中的PDML_STATUS,PDDL_STATUS,PQ_STATUS查看当前会话的默认并行状态
select PDML_STATUS,PDDL_STATUS,PQ_STATUS from v$session
另外,还可以利用如下方式查询系统的并行状态
当并行启动时,Oracle中的并行伺候进程池会根据系统中的负荷和实际因素,确定分配出的并行进程数量。此时,我们可以通过视图v$px_process来查看进程池中的连接信息。
select * from v$px_process;
注意:并行伺候进程是一种特殊的Server Process,本质上是一种可共享的slave进程。专用连接模式下,一般的Server Process与Client Process是“同生共死”的关系,终身服务于一个Client Process。而伺候slave进程是通过进程池进行管理的,一旦启动初始化,就会在一定时间内驻留在系统中,等待下次并行处理到来。
此时,我们检查v$process视图,也可以找到对应的信息。
SQL> select * from v$process;
PID SPID PNAME USERNAME SERIAL# PROGRAM
-------- ---------- ------------------------ ----- --------------- ---------- -------------------------------
25 5776 P000 oracle 13 oracle@oracle11g(P000)
26 5778 P001 oracle 6 oracle@oracle11g(P001)
(篇幅原因,有省略……)
32 rows selected
对应的OS中,也存在相应的真实进程伺候。
$ ps -ef | grep oracle
(篇幅原因,有省略……)
oracle 5700 1 0 17:29 ? 00:00:02 oraclewilson (LOCAL=NO)
oracle 5723 1 0 17:33 ? 00:00:00 ora_smco_wilson
oracle 5764 1 2 17:40 ? 00:00:05 oraclewilson (LOCAL=NO)
oracle 5774 1 0 17:42 ? 00:00:00 oraclewilson (LOCAL=NO)
oracle 5776 1 0 17:43 ? 00:00:00 ora_p000_wilson
oracle 5778 1 0 17:43 ? 00:00:00 ora_p001_wilson
oracle 5820 1 1 17:44 ? 00:00:00 ora_w000_wilson
并行操作进程的资源消耗,通过v$px_sysstat视图查看。
SQL> col statistic for a30;
SQL> select * from v$px_process_sysstat;
STATISTIC VALUE
------------------------------ ----------
Servers In Use 0
Servers Available 0
Servers Started 2
Servers Shutdown 2
Servers Highwater 2
Servers Cleaned Up 0
Server Sessions 6
Memory Chunks Allocated 4
Memory Chunks Freed 0
Memory Chunks Current 4
Memory Chunks HWM 4
Buffers Allocated 30
Buffers Freed 30
Buffers Current 0
Buffers HWM 8
15 rows selected
如果你发现降级的并行导致了令人失望的性能,你可能想重新审查你的系统资源(内存,IO带宽),调度并行SQL,或者重新检查服务器配置。可能的选择包括:
重新调度SQL,以便它们不要并发运行。Oracle 11g R2可以自动调度SQL,只要你设置“PARALLEL_ DEGREE_POLICY”参数为“AUTO”。
调整并行配置参数,以支持更大的并发并行。你可以通过增加“PARALLEL_THREADS_PER_ CPU”或者“PARALLEL_MAX_SERVERS”的值来做到这一点。这里的风险是并行执行的总量将会比你系统能支持的数量要多,这会导致SQL 性能退化。
增加你数据库服务器的性能。你可以增加CPU数量,RAC集群中实例的数量,你磁盘阵列中磁盘的数量。
调整“PARALLEL_MIN_PERCENT ”参数,使SQL可以运行在较少的并行状态下,而不是报错。
参考至:《让Oracle跑得更快》谭怀远著
《让Oracle跑得更快2》谭怀远著
http://howe.im/%E6%95%B0%E6%8D%AE%E5%BA%93/137.html
http://www.cnblogs.com/daduxiong/archive/2010/08/24/1807427.html
http://www.searchdatabase.com.cn/showcontent_44070.htm
http://xuguohao.gotoip55.com/?p=142
http://blog.csdn.net/tianlesoftware/article/details/5854583
http://docs.oracle.com/cd/E11882_01/server.112/e17110/initparams176.htm
http://space.itpub.net/17203031/viewspace-696389
本文转自:http://czmmiao.iteye.com/blog/1487568