读书人

并行操作(并行Query跟DML)以及监控

发布时间: 2013-01-26 13:47:02 作者: rapoo

并行操作(并行Query和DML)以及监控

1,并行扫描分区表
按照ROWID扫描分区表:
select /*+ PARALLEL(SALES,9)*/ * FROM SALES;

V$PQ_TQSTAT:可以查看包含并行执行操作上的统计量.帮助在一个查询中测定不平衡的问题. 最好是每个并行的servers最好工作量差不多。可以看出每个从属进程的处理的数。只有发出并行语句的SQL的session才可以看,其他的session看不到。
SQL> select * from v$pq_tqstat;

DFO_NUMBER TQ_ID SERVER_TYPE NUM_ROWS BYTES OPEN_TIME AVG_LATENCY WAITS TIMEOUTS PROCESS

INSTANCE
---------- ---------- ---------------------------------------- ---------- ---------- ---------- ----------- ---------- ---------- ---------------------------------------- ----------
1 0 Producer 103114 3851028 0 0 13 0 P008 1
1 0 Producer 104775 3892852 0 0 13 0 P007 1
1 0 Producer 98771 3672836 0 0 12 0 P006 1
1 0 Producer 102038 3797736 0 0 13 0 P005 1
1 0 Producer 98982 3694298 0 0 14 0 P003 1
1 0 Producer 104311 3877078 0 0 13 0 P004 1
1 0 Producer 100393 3715209 0 0 12 0 P002 1
1 0 Producer 105659 3927959 0 0 13 0 P001 1
1 0 Producer 100800 3742268 0 0 14 0 P000 1
1 0 Consumer 918843 34171264 0 0 18 11 QC 1

10 rows selected.


2, 并行扫描索引分区
并行可以在分区间的表和索引上执行,前提是提示(hint)里必须有表名,索引名和并行度(DOP).
例如:
select /*+ parallel_index(s,SALES_PROD_BIX,3) */ * from sales s;

3,智能化分区连接(partitionwise join)
a,Partial partitionwise join
一个表T1有3个分区,一个表T2没有分区,但是他们是通过ID连接的 T1.id=T2.id,
假设DOP=3,则T1表上三个SERVERS同时并行扫描,然后通过广播的方式扫描T2表,
此时T2表会被动态的分成三份。
b,Full partitionwise join(即两个表示equi-partitioned)

4,并行DML
a, 打开alter session enable parallel dml;
b, 先是QUERY,后进行UPDATE
c, 即使DML disable, QUERY并行还是可以的。
d, session 的DML默认是Disable
分区表特别适合做并行
例如:
alter session enable parallel DML;

drop table t1 purge;
create table t1 as select * from sales where rownum<5000;

SQL> set autotrace traceonly exp
SQL> update /*+ parallel(t1,4) */ t1 set amount_sold=amount_sold*1.1;

4999 rows updated.


Execution Plan
----------------------
Plan hash value: 121765358

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4999 | 64987 | 2 (0)| 00:00:01 | | | |
| 1 | UPDATE | T1 | | | | | | | |
| 2 | PX COORDINATOR | | | | | | | | |
| 3 | PX SEND QC (RANDOM)| :TQ10000 | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 4 | PX BLOCK ITERATOR | | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL| T1 | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |
---------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement

#从这里的执行计划可以看到,update语句在PX COORDINATOR之上,明显是进行串行update。这时我们打开alter session enable parallel dml开关,如下会报错。因为前面那个事务还没有结束。
SQL> alter session enable parallel DML;
ERROR:
ORA-12841: Cannot alter the session parallel DML state within a transaction

SQL> rollback;

Rollback complete.

SQL> alter session enable parallel dml;

Session altered.

SQL> update /*+ parallel(t1,4) */ t1 set amount_sold=amount_sold*1.1;

27 rows updated.


Execution Plan
----------------------
ERROR:
ORA-12838: cannot read/modify an object after modifying it in parallel


SP2-0612: Error generating AUTOTRACE EXPLAIN report

#因为这里实现了并行dml,因此针对plan_table的insert也变成并行了,针对同一个事务中,不能查询被并行dml了的表,所以这里报错。

SQL> rollback;

Rollback complete.

SQL> set autotrace off;
SQL> explain plan for update /*+ parallel(t1,4) */ t1 set amount_sold=amount_sold*1.1;

Explained.

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------

-------
Plan hash value: 3991856572

---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------
| 0 | UPDATE STATEMENT | | 4999 | 64987 | 2 (0)| 00:00:01 | | | |
| 1 | PX COORDINATOR | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10000 | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | P->S | QC (RAND) |
| 3 | UPDATE | T1 | | | | | Q1,00 | PCWP | |
| 4 | PX BLOCK ITERATOR | | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | PCWC | |
| 5 | TABLE ACCESS FULL| T1 | 4999 | 64987 | 2 (0)| 00:00:01 | Q1,00 | PCWP | |

PLAN_TABLE_OUTPUT
-----------------------------------------------------------------------------------------

-------
---------------------------------------------------------------------------

Note
-----
- dynamic sampling used for this statement

16 rows selected.

查看这里真正的并行dml的执行计划,可以看到,update语句是作为PX COORDINATOR的儿子存在,并且update对应的是PCPW操作,而不是P->S的操作。很明显,这里检索记录使用了并行,同时更新也是用了并行。

SQL> alter session enable parallel dml;

Session altered.

SQL> update /*+ parallel(t1,4) */ t1 set amount_sold=amount_sold*1.1;

4999 rows updated.

SQL> update t1 set amount_sold=amount_sold*1.1 where rownum=1;
update t1 set amount_sold=amount_sold*1.1 where rownum=1
*
ERROR at line 1:
ORA-12838: cannot read/modify an object after modifying it in parallel
注意:ORA-12838 错误表示只要是enable parallel dml,这个时候一个对象被并行更新后(没有commit or rollback)是不能进行read or update的。当然其他的session 对此表的操作部受影响的。只是对自己的session受影响。当然如果alter session disable parallel dml; 再进行并行的更新后,是可以进行read or update的。看下面例子:
SQL> alter session disable parallel dml;

Session altered.

SQL> update /*+ parallel(t1,4) */ t1 set amount_sold=amount_sold*1.1;

4999 rows updated.

SQL> update t1 set amount_sold=amount_sold*1.1 where rownum=1;

1 row updated.
第一个SQL做了并行后,我没有commit or rollback,下面一个SQL语句是可以做更新的。

注意:parallel_adaptive_multi_user设置为true的话,系统会自动的调整你的parallel的值,不会生成你的需要的期望值。设置成false就可以了。

并行DML详解:
update和delete语句的并行分为2部分,一部分是检索数据,而另一部分则是更新数据。
如果在update语句和delete语句里添加parallel提示,但是没有设置alter session enable parallel dml。则这时仅仅是update和delete语句中的检索数据的部分
会启用并行,实际更新的时候仍然是串行。但是,如果同时设置了alter session enable parallel dml,则检索数据和更新数据都会使用并行。

关于并行的一些视图信息:
V$PX_SESSION
V$PX_PROCESS
V$PX_SESSTAT
V$PQ_SESSTAT

读书人网 >其他数据库

热点推荐