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