精华内容
参与话题
问答
  • Parallel 并行技术

    2008-05-12 11:25:37
    Parallel 技术 对于一个大的任务,一般的做法是利用一个进程,串行的执行,如果系统资源足够,可以采用parallel技术,把一个大的任务分成若干个小的任务,同时启用n个进程/线程,并行的处理这些小的任务,这些并发...

    Parallel 技术

    对于一个大的任务,一般的做法是利用一个进程,串行的执行,如果系统资源足够,可以采用parallel技术,把一个大的任务分成若干个小的任务,同时启用n个进程/线程,并行的处理这些小的任务,这些并发的进程称为并行执行服务器(parallel executeion server),这些并发进程由一个称为并发协调进程的进程来管理。

    启用Parallel 前的忠告:只有在需要处理一个很大的任务,如需要几十分钟,几个小时的作业中,并且要有足够的系统资源的情况下(这些资源包括cpu,内存,io),您才应该考虑使用parallel。否则,在一个多并发用户下,系统本身资源负担已经很大的情况下,启用parallel,将会导致某一个会话试图占用了所有的资源,其他会话不得不去等待,从而导致系统系能反而下降的情况,一般情况下,oltp系统不要使用paralleloltp系统中可以考虑去使用。

     

    Parallel 分类

    l         并行查询 parallel query

    l         并行dml parallel dml pdml

    l         并行ddl parallel ddl pddl

     

    l         并行查询

    并行查询允许将一个sql select 语句划分为多个较小的查询,每个部分的查询并发地运行,然后将各个部分的结果组合起来,提供最终的结果,多用于全表扫描,索引全扫描等,大表的扫描和连接、创建大的索引、分区索引扫描、大批量插入更新和删除

     

    启用并行查询

    SQL> ALTER TABLE T1 PARALLEL;

    告知oracle,对T1启用parallel查询,但并行度要参照系统的资源负载状况来确定。

    利用hints 提示,启用并行,同时也可以告知明确的并行度,否则oracle自行决定启用的并行度,这些提示只对该sql语句有效。

    SQL> select /*+ parallel(t1 8) */ count(*) from t1;

     

    SQL> select degree from user_tables where table_name='T1';

    DEGREE

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

       DEFAULT

     

    并行度为Default 其值由下面2个参数决定

    SQL> show parameter cpu

     

    NAME                                 TYPE        VALUE

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

    cpu_count                            integer     2

    parallel_threads_per_cpu             integer     2

     

    cpu_count 表示cpu

    parallel_threads_per_cpu表示每个cpu允许的并行进程数

    default情况下,并行数为cpu_count*parallel_threads_per_cpu

     

    取消并行设置

    SQL> alter table t1 noparallel;

    SQL> select degree from user_tables where table_name='T1';

     

    DEGREE

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

             1

     

    数据字典视图

    v$px_session

    sid:各个并行会话的sid

    qcsidquery coordinator sid,查询协调器sid

     

    l         并行dml

    并行dml 包括insertupdatedeletemerge,在pdml期间,oracle可以使用多个并行执行服务器来执行insertupdatedeletemerge,多个会话同时执行,同时每个会话(并发进程)都有自己的undo段,都是独立的一个事务,这些事务要么由pdml协调器进程提交,要么都rollback

    在一个有充足I/o带宽的多cpu主机中,对于大规模的dml,速度可能会有很大的提升,尤其是在大型的数据仓库环境中。

    并行dml需要显示的启用

    SQL> alter session enable parallel dml;

     

    Disable 并行dml

    SQL> alter session disable parallel dml;

     

    l         并行ddl

    并行ddl提供了dba使用全部机器资源的能力,常用的pddl

    create table as select  ……

    create index

    alter index rebuild

    alter table move

    alter table split

    在这些sql语句后面加上parallel 子句

    SQL> alter table t1 move parallel;

    Table altered

    SQL> create index T1_IDX on T1 (OWNER, OBJECT_TYPE)

      2    tablespace SYSTEM

    3         parallel;

    4        

     

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10159839/viewspace-265127/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/10159839/viewspace-265127/

    展开全文
  • /*+parallel(t,4)*/在SQL调优中的重要作用! 2013年11月17日 12:59:24 雾里看花5566 阅读数:5422更多 个人分类: 数据库-oracle 谈谈HINT /*+parallel(t,4)*/在SQL调优中的重要作用! /*+parallel(t,4)*/在大...

     

    /*+parallel(t,4)*/在SQL调优中的重要作用!

    2013年11月17日 12:59:24 雾里看花5566 阅读数:5422更多

    个人分类: 数据库-oracle

    谈谈HINT /*+parallel(t,4)*/在SQL调优中的重要作用!

    /*+parallel(t,4)*/在大表查询等操作中能够起到良好的效果,
    基于并行查询要启动并行进程、分配任务与系统资源、合并结果集,这些都是比较消耗资源,
    但我们为能够减少执行事务的时间使用parallel HINT还是值得的,尤其在ODS系统中报表统计等方面更有使用意义.
    一般而言主要在如下情况使用parallel HINT
    1.表的数据量很大,超过一千万; 
    2.数据库主机是多个CPU;
    3.系统的当前负载较低;

    简单的测试如下,效果很明显的:

    
     
    1. SQL> select /*+parallel(t,4)*/count(*) from t;

    2.  
    3. COUNT(*)

    4. ----------

    5. 30245882

    6.  
    7. 已用时间: 00: 01: 32.04

    8.  
    9. Execution Plan

    10. ----------------------------------------------------------

    11. 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5411 Card=1)

    12. 1 0 SORT (AGGREGATE)

    13. 2 1 SORT* (AGGREGATE) :Q351880

    14. 00

    15.  
    16. 3 2 TABLE ACCESS* (FULL) OF 't' (Cost=5411 Car :Q351880

    17. d=2822493) 00

    18.  
    19.  
    20.  
    21. 2 PARALLEL_TO_SERIAL SELECT /*+ PIV_SSF */ SYS_OP_MSR(COUNT(*)) F

    22. ROM (SELECT /*+ NO_EXPAND ROWID(A2)

    23.  
    24. 3 PARALLEL_COMBINED_WITH_PARENT

    25.  
    26. SQL> select count(*) from t;

    27.  
    28. COUNT(*)

    29. ----------

    30. 30245882

    31.  
    32. 已用时间: 00: 04: 34.02

    33.  
    34. Execution Plan

    35. ----------------------------------------------------------

    36. 0 SELECT STATEMENT Optimizer=CHOOSE

    37. 1 0 SORT (AGGREGATE)

    38. 2 1 TABLE ACCESS (FULL) OF 't'

    39.  
    40.  
    41.  
    42. SQL>

    https://blog.csdn.net/u012354280/article/details/16369149

     

     

    Oracle并行模式(Parallel)

    2017年09月06日 18:00:39 白开水Luis 阅读数:5815

    1. 实例

    (1)insert 加速

    insert into /*+ append parallel nologging */ dcustcomposmsg 
    select /*+ parallel(e,18)*/ * from dcustcomposmsg_new e; 
    commit;

    (2)select create加速
    CREATE TABLE TEMP_DCUST_GRADE  NOLOGGING PARALLEL 10 AS
                       SELECT /*+PARALLEL(D,10)*/ *
                        FROM DCUST_BASIC_INFO_D PARTITION (P_'||V_TOLL_NO||') D 
                       WHERE EXISTS(SELECT ''A'' FROM DCUSTHIGH PARTITION (P_'||V_REGION_CODE||') A
                       WHERE D.ID_NO = A.ID_NO )

    2. 用途

    强行启用并行度来执行当前SQL。这个在Oracle 9i之后的版本可以使用,之前的版本现在没有环境进行测试。也就是说,加上这个说明,可以强行启用Oracle的多线程处理功能。举例的话,就像电脑装了多核的CPU,但大多情况下都不会完全多核同时启用(2核以上的比较明显),使用parallel说明,就会多核同时工作,来提高效率。

    但本身启动这个功能,也是要消耗资源与性能的。所有,一般都会在返回记录数大于100万时使用,效果也会比较明显。

    3. 语法
    /*+parallel(table_short_name,cash_number)*/

    这个可以加到insert、delete、update、select的后面来使用(和rule的用法差不多,有机会再分享rule的用法)

    开启parallel功能的语句是:

    alter session enable parallel dml;

    这个语句是DML语句哦,如果在程序中用,用execute的方法打开。

    4. 实例说明

    用ERP中的transaction来说明下吧。这个table记录了所有的transaction,而且每天数据量也算相对比较大的(根据企业自身业务量而定)。假设我们现在要查看对比去年一年当中每月的进、销情况,所以,一般都会写成:

    select to_char(transaction_date,'yyyymm') txn_month,

           sum(

            decode(

                sign(transaction_quantity),1,transaction_quantity,0
                  )

              ) in_qty,

           sum(

            decode(

                sign(transaction_quantity),-1,transaction_quantity,0
                  )

              ) out_qty

      from mtl_material_transactions mmt

    where transaction_date >= add_months(

                                to_date(    

                                    to_char(sysdate,'yyyy')||'0101','yyyymmdd'),

                                    -12)

       and transaction_date <= add_months(

                                to_date(

                                    to_char(sysdate,'yyyy')||'1231','yyyymmdd'),

                                    -12)

    group by to_char(transaction_date,'yyyymm') 

    这个SQL执行起来,如果transaction_date上面有加index的话,效率还算过的去;但如果没有加index的话,估计就会半个小时内都执行不出来。这是就可以在select 后面加上parallel说明。例如:
    select /*+parallel(mmt,10)*/
           to_char(transaction_date,'yyyymm') txn_month,

    ...



    这样的话,会大大提高执行效率。如果要将检索出来的结果insert到另一个表tmp_count_tab的话,也可以写成:
    insert /*+parallel(t,10)*/
      into tmp_count_tab

    (

        txn_month,

        in_qty,

        out_qty

    )

    select /*+parallel(mmt,10)*/
           to_char(transaction_date,'yyyymm') txn_month,

    ...



    插入的机制和检索机制差不多,所以,在insert后面加parallel也会加速的。关于insert机制,这里暂不说了。
    Parallel后面的数字,越大,执行效率越高。不过,貌似跟server的配置还有oracle的配置有关,增大到一定值,效果就不明显了。所以,一般用8,10,12,16的比较常见。我试过用30,发现和16的效果一样。不过,数值越大,占用的资源也会相对增大的。如果是在一些package、function or procedure中写的话,还是不要写那么大,免得占用太多资源被DBA开K。
      

    5. Parallel也可以用于多表

    多表的话,就是在第一后面,加入其他的就可以了。具体写法如下:

    /*+parallel(t,10) (b,10)*/

    6. 小结

    关于执行效率,建议还是多按照index的方法来提高效果。Oracle有自带的explan road的方法,在执行之前,先看下执行计划路线,对写好的SQL tuned之后再执行。实在没办法了,再用parallel方法。Parallel比较邪恶,对开发者而言,不是好东西,会养成不好习惯,导致很多bad SQL不会暴漏,SQL Tuning的能力得不到提升。我有见过某些人create table后,从不create index或primary key,认为写SQL时加parallel就可以了。

     

     

    https://blog.csdn.net/zhanglu0223/article/details/77869553

     

    Oracle Hints详解

    2011年12月23日 20:30:51 米菲的泰迪 阅读数:25940 标签: oracletable优化parallelinsertmerge更多

    个人分类: Oracle

    在向大家详细介绍Oracle Hints之前,首先让大家了解下Oracle Hints是什么,然后全面介绍Oracle Hints,希望对大家有用。基于代价的优化器是很聪明的,在绝大多数情况下它会选择正确的优化器,减轻了DBA的负担。但有时它也聪明反被聪明误,选择了很差的执行计划,使某个语句的执行变得奇慢无比。


    此时就需要DBA进行人为的干预,告诉优化器使用我们指定的存取路径或连接类型生成执行计划,从而使语句高效的运行。例如,如果我们认为对于一个特定的语句,执行全表扫描要比执行索引扫描更有效,则我们就可以指示优化器使用全表扫描。在Oracle中,是通过为语句添加 Hints(提示)来实现干预优化器优化的目的。


    Oracle Hints是一种机制,用来告诉优化器按照我们的告诉它的方式生成执行计划。我们可以用Oracle Hints来实现:
    1) 使用的优化器的类型
    2) 基于代价的优化器的优化目标,是all_rows还是first_rows。
    3) 表的访问路径,是全表扫描,还是索引扫描,还是直接利用rowid。
    4) 表之间的连接类型
    5) 表之间的连接顺序
    6) 语句的并行程度


      2、HINT可以基于以下规则产生作用
      表连接的顺序、表连接的方法、访问路径、并行度


    除了”RULE”提示外,一旦使用的别的提示,语句就会自动的改为使用CBO优化器,此时如果你的数据字典中没有统计数据,就会使用缺省的统计数据。所以建议大家如果使用CBO或Hints提示,则最好对表和索引进行定期的分析。


    如何使用Hints:


    Hints只应用在它们所在sql语句块(statement block,由select、insert、update、delete关键字标识)上,对其它SQL语句或语句的其它部分没有影响。如:对于使用union操作的2个 sql语句,如果只在一个sql语句上有Hints,则该Hints不会影响另一个sql语句。


    我们可以使用注释(comment)来为一个语句添加Hints,一个语句块只能有一个注释,而且注释只能放在SELECT, UPDATE, or DELETE关键字的后面


    使用Oracle Hints的语法:


    {DELETE|INSERT|SELECT|UPDATE} /*+ hint [text] [hint[text]]... */

    or

    {DELETE|INSERT|SELECT|UPDATE} --+ hint [text] [hint[text]]...


    注解:
    1) DELETE、INSERT、SELECT和UPDATE是标识一个语句块开始的关键字,包含提示的注释只能出现在这些关键字的后面,否则提示无效。
    2) “+”号表示该注释是一个Hints,该加号必须立即跟在”/*”的后面,中间不能有空格。
    3) hint是下面介绍的具体提示之一,如果包含多个提示,则每个提示之间需要用一个或多个空格隔开。
    4) text 是其它说明hint的注释性文本


    如果你没有正确的指定Hints,Oracle将忽略该Hints,并且不会给出任何错误。

    1. /*+ALL_ROWS*/
      表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.
      例如:
      SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT'; 
      2. /*+FIRST_ROWS*/
      表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.
      例如:
      SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
      3. /*+CHOOSE*/
      表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;
      表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;
      例如:
      SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
      4. /*+RULE*/
      表明对语句块选择基于规则的优化方法.
      例如:
      SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='SCOTT';
      5. /*+FULL(TABLE)*/
      表明对表选择全局扫描的方法.
      例如:
      SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='SCOTT';
      6. /*+ROWID(TABLE)*/
      提示明确表明对指定表根据ROWID进行访问.
      例如:
      SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'
      AND EMP_NO='SCOTT';
      7. /*+CLUSTER(TABLE)*/ 
      提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.
      例如:
      SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
      WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      8. /*+INDEX(TABLE INDEX_NAME)*/
      表明对表选择索引的扫描方法.
      例如:
      SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';
      9. /*+INDEX_ASC(TABLE INDEX_NAME)*/
      表明对表选择索引升序的扫描方法.
      例如:
      SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';
      10. /*+INDEX_COMBINE*/
      为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的布尔组合方式.
      例如:
      SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
      WHERE SAL<5000000 AND HIREDATE
      11. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
      提示明确命令优化器使用索引作为访问路径.
      例如:
      SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
      FROM BSEMPMS WHERE SAL<60000;
      12. /*+INDEX_DESC(TABLE INDEX_NAME)*/
      表明对表选择索引降序的扫描方法.
      例如:
      SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='SCOTT';
      13. /*+INDEX_FFS(TABLE INDEX_NAME)*/
      对指定的表执行快速全索引扫描,而不是全表扫描的办法.
      例如:
      SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';
      14. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
      提示明确进行执行规划的选择,将几个单列索引的扫描合起来.
      例如:
      SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='SCOTT' AND DPT_NO='TDC306';
      15. /*+USE_CONCAT*/
      对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.
      例如:
      SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';
      16. /*+NO_EXPAND*/
      对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.
      例如:
      SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';
      17. /*+NOWRITE*/
      禁止对查询块的查询重写操作.
      18. /*+REWRITE*/
      可以将视图作为参数.
      19. /*+MERGE(TABLE)*/
      能够对视图的各个查询进行相应的合并.
      例如:
      SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
      ,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
      AND A.SAL>V.AVG_SAL;
      20. /*+NO_MERGE(TABLE)*/
      对于有可合并的视图不再合并.
      例如:
      SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELECT DPT_NO,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO AND A.SAL>V.AVG_SAL;
      21. /*+ORDERED*/
      根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.
      例如:
      SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;
      22. /*+USE_NL(TABLE)*/
      将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.
      例如:
      SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      23. /*+USE_MERGE(TABLE)*/
      将指定的表与其他行源通过合并排序连接方式连接起来.
      例如:
      SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      24. /*+USE_HASH(TABLE)*/
      将指定的表与其他行源通过哈希连接方式连接起来.
      例如:
      SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;
      25. /*+DRIVING_SITE(TABLE)*/
      强制与ORACLE所选择的位置不同的表进行查询执行.
      例如:
      SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;
      26. /*+LEADING(TABLE)*/
      将指定的表作为连接次序中的首表.
      27. /*+CACHE(TABLE)*/
      当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
      例如:
      SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
      28. /*+NOCACHE(TABLE)*/
      当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
      例如:
      SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;
      29. /*+APPEND*/
      直接插入到表的最后,可以提高速度.
      insert /*+append*/ into test1 select * from test4 ;
      30. /*+NOAPPEND*/
      通过在插入语句生存期内停止并行模式来启动常规插入.
      insert /*+noappend*/ into test1 select * from test4 ;
     31. NO_INDEX: 指定不使用哪些索引


      /*+ NO_INDEX ( table [index [index]...] ) */


      select /*+ no_index(emp ind_emp_sal ind_emp_deptno)*/ * from emp where deptno=200 and sal>300;


      32. parallel


      select /*+ parallel(emp,4)*/ * from emp where deptno=200 and sal>300;


      另:每个SELECT/INSERT/UPDATE/DELETE命令后只能有一个/*+ */,但提示内容可以有多个,可以用逗号分开,空格也可以。


      如:/*+ ordered index() use_nl() */


    ---------
    类似如下的一条语句:insert into xxxx select /*+parallel(a) */ * from xxx a;数据量大约在75G左右,这位兄弟从上午跑到下午还没跑完,过来问我咋回事,说平常2hrs能跑完的东西跑了好几个小时还撒动静。查看系统性能也比较 正常,cpu,io都不繁忙,平均READ速度在80M/s左右(勉强凑合),但平均写速度只有10M不到。等待事件里面大量的‘ ‘PX Deq Credit: send blkd’,这里能看出并行出了问题,从而最后得知是并行用法有问题,修改之后20分钟完成了该操作。正确的做法应该是:
    alter session enable dml parallel;


    insert /*+parallel(xxxx,4) */ into xxxx select /*+parallel(a) */ * from xxx a;


    因为oracle默认并不会打开PDML,对DML语句必须手工启用。 另外不得不说的是,并行不是一个可扩展的特性,只有在数据仓库或作为DBA等少数人的工具在批量数据操作时利于充分利用资源,而在OLTP环境下使用并行 需要非常谨慎。事实上PDML还是有比较多的限制的,例如不支持触发器,引用约束,高级复制和分布式事务等特性,同时也会带来额外的空间占用,PDDL同 样是如此。有关Parallel excution可参考官方文档,在Thomas Kyte的新书《Expert Oracle Database architecture》也有精辟的讲述。
    ---------
    select count(*)
      From wid_serv_prod_mon_1100 a
     where a.acct_month = 201010
       and a.partition_id = 10
       and serv_state not in ('2HB', '2HL', '2HJ', '2HP', '2HF')
       and online_flag in (0)
       and incr_product_id in (2000020)
       and product_id in (2020966, 2020972, 2100297, 2021116)
       and billing_mode_id = 1
       and exp_date > to_date('201010', 'yyyymm')
       and not exists (select /*+no_index (b IDX_W_CDR_MON_SERV_ID_1100)*/
             1
              from wid_cdr_mon_1100 b
             where b.acct_month = 201010
               and b.ANA_EVENT_TYPE_4 in
                   ('10201010201', '10202010201', '10203010201', '10203010202', '10203030201', '10203030202', '10204010201', '10204010202', '10204030201')
               and a.serv_id = b.serv_id)

     

    https://blog.csdn.net/wb96a1007/article/details/7098687

     

     

     

    alter session enable parallel dml

    2013年06月16日 00:11:41 luckman100 阅读数:3840更多

    个人分类: 性能优化

    之前我一直不理解为什么做并行DML之前要加上:alter session enable parallel dml,因为有一个假象蒙蔽了我:

    下面的执行计划是没有执行alter session enable parallel dml产生的:

    EXPLAIN PLAN FOR UPDATE/*+parallel(t 8)*/ test1 t SET object_id=1;

    SELECT * FROM table (DBMS_XPLAN.display(NULL, NULL, 'BASIC +PARALLEL'));

    当我看到执行计划里面有Q1,00这样的描述,就以为并行度hint生效了,但是我没注意到,这里并行度只用在对test1表的全盘扫描上,并没有用在update上!!!!!其实这还是远远不够的。下面是执行了alter session enable parallel dml产生的执行计划:

    这里可以看到执行计划上的差别:这次不止全盘扫描时用到了并行度,而且update时也用上了并行度,这才是我们需要的!!

    最后注意要把session的并行度关掉:alter session disable parallel dml

    https://blog.csdn.net/luckyman100/article/details/9103853

     

     

    虽然没有 alter session enable parallel dml, 但是parallel的hint仍然起作用了? 

    [复制链接]

    今天晴天了

    论坛徽章:

    5

    2014年新春福章 日期:2014-02-18 16:49:31马上有钱 日期:2014-02-18 16:49:31优秀写手 日期:2014-10-28 06:00:14暖羊羊 日期:2015-03-04 14:54:572015年新春福章 日期:2015-03-06 11:59:47

    电梯直达跳转到指定楼层

    1#

     发表于 2014-3-27 08:26 | 只看该作者 回帖奖励

    做了如下操作,测试没有 alter session enable parallel dml;情况下,parallel的hint是否能起作用?

    SQL> show rel
    Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 


    SQL> alter session set sql_trace = true; 

    Session altered

    SQL> insert into big_table select * from big_table;

    74516 rows inserted

    SQL> 
    SQL> insert /*+  parallel */ into big_table select * from big_table;

    149032 rows inserted

    SQL> alter session set sql_trace = false; 

    Session altered

    找到trc文件,格式化后,看到如下:


    insert into big_table select * from big_table


    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.01          0          1          0           0
    Execute      1      0.14       0.23        792       2492       9667       74516
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      0.14       0.24        792       2493       9667       74516

    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 83  
    Number of plan statistics captured: 1

    Rows (1st) Rows (avg) Rows (max)  Row Source Operation
    ---------- ---------- ----------  ---------------------------------------------------
             0          0          0  LOAD TABLE CONVENTIONAL  (cr=2519 pr=792 pw=0 time=242928 us)
         74516      74516      74516   TABLE ACCESS FULL BIG_TABLE (cr=1066 pr=788 pw=0 time=29251 us cost=298 size=14507802 card=70086)

    ********************************************************************************

    SQL ID: gujz6hynj50d6 Plan Hash: 4182993142

    insert /*+  parallel */ into big_table select * from big_table


    call     count       cpu    elapsed       disk      query    current        rows
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    Parse        1      0.00       0.00          0          1          0           0
    Execute      1      0.23       0.66          0       2939      19303      149032
    Fetch        0      0.00       0.00          0          0          0           0
    ------- ------  -------- ---------- ---------- ---------- ----------  ----------
    total        2      0.23       0.66          0       2940      19303      149032

    Misses in library cache during parse: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 83  
    Number of plan statistics captured: 1

    Rows (1st) Rows (avg) Rows (max)  Row Source Operation
    ---------- ---------- ----------  ---------------------------------------------------
             0          0          0  LOAD TABLE CONVENTIONAL  (cr=2990 pr=0 pw=0 time=662873 us)
        149032     149032     149032   PX COORDINATOR  (cr=47 pr=0 pw=0 time=358870 us)
             0          0          0    PX SEND QC (RANDOM) :TQ10000 (cr=0 pr=0 pw=0 time=0 us cost=329 size=60410880 card=291840)
             0          0          0     PX BLOCK ITERATOR (cr=0 pr=0 pw=0 time=0 us cost=329 size=60410880 card=291840)
             0          0          0      TABLE ACCESS FULL BIG_TABLE (cr=0 pr=0 pw=0 time=0 us cost=329 size=60410880 card=291840)

    ********************************************************************************

    SQL ID: 4yhdgar8gyhxy Plan Hash: 0


    可以看到,虽然没有 alter session enable parallel dml, 但是 insert /*+  parallel */ into big_table select * from big_table仍然走了并行,这和很多地方说的不一样,为什么呢?

     

    http://www.itpub.net/thread-1852708-1-1.html

     

     

     

     

    展开全文
  • [size=medium][color=red][b] 1.用途[/b][/color][/size] 强行启用并行度来执行当前SQL。这个在Oracle 9i之后的版本可以使用,之前的版本现在没有环境进行测试。也就是说,加上这个说明,可以强行启用Oracle的多...
    [size=medium][color=red][b] 1.用途[/b][/color][/size]    
    强行启用并行度来执行当前SQL。这个在Oracle 9i之后的版本可以使用,之前的版本现在没有环境进行测试。也就是说,加上这个说明,可以强行启用Oracle的多线程处理功能。举例的话,就像电脑装了多核的CPU,但大多情况下都不会完全多核同时启用(2核以上的比较明显),使用parallel说明,就会多核同时工作,来提高效率。 但本身启动这个功能,也是要消耗资源与性能的。所以,一般都会在返回记录数大于100万时使用,效果也会比较明显。

    [size=medium][color=red][b] 2.语法[/b][/color][/size]
    /*+parallel(table_short_name,cash_number)*/ 这个可以加到insert、delete、update、select的后面来使用(和rule的用法差不多,有机会再分享rule的用法)
    开启parallel功能的语句是:
    alter session enable parallel dml;

    这个语句是DML语句哦,如果在程序中用,用execute的方法打开。

    SELECT  /*+PARALLEL(n)*/  *  FROM table


    查看Oracle能利用的最大并行度


    SQL> show parameters cpu

    NAME TYPE VALUE
    ------------------------------------ ----------- -------
    cpu_count integer 8
    parallel_threads_per_cpu integer 2
    resource_manager_cpu_allocation integer 8


    值得注意的是,在实际使用中,计算机除了运行Oracle外,同时还在运行其他程序(如系统程序)。因此,用PARALLEL调用CPU线程值应设定为小于最大CPU线程的数值(笔者一般采用的值为:CPU线程总数-2)以避免将所有CPU资源强行分配给Oracle使用后导致系统无响应等情况发生。
    展开全文
  • OpenCV 从2.4.3开始加入了并行计算的函数parallel_for和parallel_for_(更准确地讲,parallel_for以前就存在于tbb模块中,但是OpenCV官网将其列在2.4.3.的New Features中,应该是重新改写过的)。 2.4.3中自带的...

    OpenCV 从2.4.3开始加入了并行计算的函数parallel_for和parallel_for_(更准确地讲,parallel_for以前就存在于tbb模块中,但是OpenCV官网将其列在2.4.3.的New Features中,应该是重新改写过的)。

    2.4.3中自带的calcOpticalFlowPyrLK函数也用parallel_for重写过了,之前我一直认为parallel_for就是用来并行计算的,之前也自己写了一些用parallel_for实现的算法。直到今天在opencv官网中看到别人的提问,才发现parallel_for实际上是serial loop,而parallel_for_才是parallel loop(OpenCV官网answer)。

    为了比较for循环,parallel_for和parallel_for_ 三者的差异,下面做了一个简单的测试,对一个Mat中所有的元素(按列为单位)做立方操作。


    Code

    test.hpp

    /**@ Test parallel_for and parallel_for_
    /**@ Author: chouclee
    /**@ 03/17/2013*/
    #include <opencv2/core/internal.hpp>
    namespace cv
    {
    namespace test
    {
    	class parallelTestBody : public ParallelLoopBody//参考官方给出的answer,构造一个并行的循环体类
    	{
    	public:
    		parallelTestBody(Mat& _src)//class constructor
    		{
    			src = &_src;
    		}
    		void operator()(const Range& range) const//重载操作符()
    		{
    			Mat& srcMat = *src;
    			int stepSrc = (int)(srcMat.step/srcMat.elemSize1());//获取每一行的元素总个数(相当于cols*channels,等同于step1)
    			for (int colIdx = range.start; colIdx < range.end; ++colIdx)
    			{
    				float* pData = (float*)srcMat.col(colIdx).data;
    				for (int i = 0; i < srcMat.rows; ++i)
    					pData[i*stepSrc] = std::pow(pData[i*stepSrc],3);
    			}	
    		}
    
    	private:
    		Mat* src;
    	};
    
    	struct parallelTestInvoker//构造一个供parallel_for使用的循环结构体
    	{
    		parallelTestInvoker(Mat& _src)//struct constructor
    		{
    			src = &_src;
    		}
    		void operator()(const BlockedRange& range) const//使用BlockedRange需要包含opencv2/core/internal.hpp
    		{
    			Mat& srcMat = *src;
    			int stepSrc = (int)(srcMat.step/srcMat.elemSize1());
    			for (int colIdx = range.begin(); colIdx < range.end(); ++colIdx)
    			{
    				float* pData = (float*)srcMat.col(colIdx).data;
    				for (int i = 0; i < srcMat.rows; ++i)
    					pData[i*stepSrc] = std::pow(pData[i*stepSrc],3);
    			}
    		}
    		Mat* src;
    	};
    }//namesapce test
    void parallelTestWithFor(InputArray _src)//'for' loop
    {
    	CV_Assert(_src.kind() == _InputArray::MAT);
    	Mat src = _src.getMat();
    	CV_Assert(src.isContinuous());
    	int stepSrc = (int)(src.step/src.elemSize1());
    	for (int x = 0; x < src.cols; ++x)
    	{
    		float* pData = (float*)src.col(x).data;
    		for (int y = 0; y < src.rows; ++y)
    			pData[y*stepSrc] = std::pow(pData[y*stepSrc], 3);
    	}
    };
    
    void parallelTestWithParallel_for(InputArray _src)//'parallel_for' loop
    {
    	CV_Assert(_src.kind() == _InputArray::MAT);
    	Mat src = _src.getMat();
    	int totalCols = src.cols;
    	typedef test::parallelTestInvoker parallelTestInvoker;
    	parallel_for(BlockedRange(0, totalCols), parallelTestInvoker(src));
    };
    
    void parallelTestWithParallel_for_(InputArray _src)//'parallel_for_' loop
    {
    	CV_Assert(_src.kind() == _InputArray::MAT);
    	Mat src = _src.getMat();
    	int totalCols = src.cols;
    	typedef test::parallelTestBody parallelTestBody;
    	parallel_for_(Range(0, totalCols), parallelTestBody(src));
    };
    }//namespace cv
    
    main.cpp

    /**@ Test parallel_for and parallel_for_
    /**@ Author: chouclee
    /**@ 03/17/2013*/
    #include <opencv2/opencv.hpp>
    #include <time.h>
    #include "test.hpp"
    using namespace cv;
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	Mat testInput = Mat::ones(40,400000, CV_32F);
    	clock_t start, stop;
    
    	start = clock();
    	parallelTestWithFor(testInput);
    	stop = clock();
    	cout<<"Running time using \'for\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;
    
    	start = clock();
    	parallelTestWithParallel_for(testInput);
    	stop = clock();
    	cout<<"Running time using \'parallel_for\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;
    
    	start = clock();
    	parallelTestWithParallel_for_(testInput);
    	stop = clock();
    	cout<<"Running time using \'parallel_for_\':"<<(double)(stop - start)/CLOCKS_PER_SEC*1000<<"ms"<<endl;
    
    	system("pause");
    }

    Result
    输入为400000*40时,结果如下:
    Debug模式
    Running time using 'for': 1376ms
    Running time using 'parallel_for': 1316ms
    Running time using 'parallel_for_': 553ms
    Release模式
    Running time using 'for': 463ms
    Running time using 'parallel_for': 475ms
    Running time using 'parallel_for_': 301ms

    输入改为40*400000
    Debug模式
    Running time using 'for': 1005ms
    Running time using 'parallel_for': 1013ms
    Running time using 'parallel_for_': 526ms
    Release模式
    Running time using 'for': 105ms
    Running time using 'parallel_for': 106ms
    Running time using 'parallel_for_': 81ms

    输入改为4000*4000
    Debug模式
    Running time using 'for': 1138ms
    Running time using 'parallel_for': 1136ms
    Running time using 'parallel_for_': 411ms
    Release模式
    Running time using 'for': 234ms
    Running time using 'parallel_for': 239ms
    Running time using 'parallel_for_': 130ms

    大多数情况下,parallel_for比for循环慢那么一丁丁点儿,有时甚至会比for循环快一些,总体上两者差不多,parallel_for_一直都是最快的。但上面的代码只是做测试使用(因此强制按列进行操作),实际上,像上面这种简单的操作,直接对Mat使用for循环和指针递增操作,只需要几十毫秒。但是,对于复杂算法,比如光流或之类的,使用parallel_for(虽然不是并行操作,但代码简洁易于维护,且速度和for循环差不多)或者parallel_for_将是不错的选择。


    Reference:

    http://answers.opencv.org/question/3730/how-to-use-parallel_for/

    展开全文
  • Parallel 简单总结

    2017-08-31 17:01:21
    Parallel Parallel 主要提供了For 系列方法和ForEach 系列方法,并行处理所有项。两个系列的方法都有若干重载,但最常用也最易用的是这两个。并行的目的是高效处理耗时计算 一////////Parallel.For(int ...
  • 深入浅出parallelStream

    万次阅读 多人点赞 2016-10-12 09:42:39
    about Stream什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户...
  • PCB的principal

    2020-09-29 15:25:30
    写在前面 我们之前说过了怎么制作原理图库,今天我们来说一说怎么绘制PCB图库,每一个元件都有自己的说明书或者我们称之为技术手册,我们可以从这些技术手册上面来获得元件PCB封装的相关信息,比如尺寸和引脚间距等...
  • 到那里之后发现,她用的是macbook,在mac上装了parallel Desktop 装了一个win10的虚拟机 苹果本可以正常上网,但是虚拟机死活上不了网。win10上网那个小电脑标志没有感叹号,也没有X,微信qq上不了,网页也上不了 ...
  • Stream和parallelStream

    万次阅读 多人点赞 2019-04-22 15:16:54
    Stream 和 parallelStream 一.什么是Stream? Stream 是在 Java8 新增的特性,普遍称其为流;它不是数据结构也不存放任何数据,其主要用于集合的逻辑处理。 二.和Iterator的区别 Iterator 做为迭代器,其按照一定的...
  • This book was written to help you use Intel Parallel Studio XE to write programs that use the latest features of multicore CPUs. With the help of this book, you should be able to produce code that is ...
  • Python并行运算模块Parallel Python简介

    万次阅读 2016-11-17 09:59:22
    一、概览PP是一个python模块,提供在SMP(具有多个处理器或多核的系统)和集群(通过网络连接的计算机)上并行执行python代码的机制。它轻巧,易于安装和与其他python软件集成。PP是一个用纯Python编写的开源和跨...
  • pytorch 多GPU训练总结(DataParallel的使用)

    万次阅读 多人点赞 2019-02-28 18:35:52
    这里记录用pytorch 多GPU训练 踩过的许多坑 仅针对单服务器多gpu 数据并行 而不是 多机器分布式训练 一、官方思路包装模型 这是pytorch 官方的原理图 按照这个官方的原理...上文也用dataParallel 包装了optimize...
  • GNU Parallel指南

    2018-07-04 15:30:00
    GNU Parallel 它是什么? GNU Parallel是一个shell工具,为了在一台或多台计算机上并行的执行计算任务,一个计算任务可以是一条shell命令或者一个以每一行做为输入的脚本程序。通常的输入是文件列表、主机列表、...
  • Oracle Parallel Execution

    千次阅读 2013-12-14 15:01:54
    PARALLEL_DEGREE_POLICY  Specifies whether or not automatic degree of Parallelism,statement queuing, and in-memory parallel execution will be enabled. MANUAL is the default, which disables automatic d
  • Stream是Java8新引入的API,有着广泛的运用 创建一个Stream Stream创建之后,就不能修改 创建一个空的Stream ...StreamString> streamEmpty = Stream.empty();...public StreamString> streamOf(ListString> list) ...
  • Parallel Scavenge: 是与ParNew类似,都是用于年轻代回收的使用复制算法的并行收集器,与ParNew不同的是,Parallel Scavenge的目标是达到一个可控的吞吐量,吞吐量=程序运行时间/(程序运行时间+GC时间),如程序...
  • Parallel-Programming-with-Intel-Parallel-Studio-XE-Wrox-Programmer-to-Programmer, 资源来自于互联网
  • 现在Pytorc下进行多卡训练主流的是采用torch.nn.parallel.DistributedDataParallel()(DDP)方法,但是在一些特殊的情况下这样的方法就使用不了了,特别是在进行与GAN相关的训练的时候,假如使用的损失函数是 WGAN-...
  • 对比Parallel Scavenge/Parallel Old与Serial/Serial Old内存分配策略区别
  • Parallel Scavenge无法和CMS共同使用

    万次阅读 2019-05-01 11:35:15
    ParNewGeneration是parallel new generation         原本HotSpot VM没有并行GC,当时就只有NewGeneration;后来准备要加入young gen的并行GC,就把原本的NewGe...
  • postgresql 11 的并行(parallel)简介

    千次阅读 2018-11-14 10:39:57
    postgresql 11 的并行(parallel)简介 os:centos 7.4 db:postgresql 11.1 postgresql 11 对parallel又有了进一步的加强 。 并行创建btree索引 使用共享hash table时可以并行执行hash join 单个选择如果不能...
  • 我也曾经有过这种感觉,直到我发现了 GNU Parallel。 GNU Parallel 是一个 shell 工具,可以并行执行任务。它可以解析多种输入,让你可以同时在多份数据上运行脚本或命令。你终于可以使用全部的 ...
  • 深入浅出Stream和parallelStream

    万次阅读 多人点赞 2018-02-07 18:25:17
    深入浅出parallelStream 什么是流? Stream是java8中新增加的一个特性,被java猿统称为流. Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 ...
  • Parallel Processing 当执行一个 sql 语句时 , 缺省是用一个 cpu 来连续执行 , 不管有多少个...
  • db file parallel write 等待事件引自如下blog:http://oradbpedia.com/wiki/Wait_Events_-_db_file_parallel_write db file parallel write The db file parallel write wait event belongs to the Or
  • import operator import torch import warnings from itertools import chain from ..modules import Module from .scatter_gather import ...from .parallel_apply import parallel_apply from torch.cuda._utils imp.
  • 我也曾经有过这种感觉,直到我发现了 GNU Parallel。GNU Parallel 是一个 shell 工具,可以并行执行任务。它可以解析多种输入,让你可以同时在多份数据上运行脚本或命令。你终于可以使用全部的 CPU 了!如果你用过 ...
  • 接着之前写的并行算法parallel包,parallel相比foreach来说,相当于是foreach的进阶版,好多东西封装了。而foreach包更为基础,而且可自定义的内容很多,而且实用性比较强,可以简单的用,也可以用得很复杂。笔者将...
  • Parallel Computing with MATLAB

    千次阅读 2013-11-24 13:48:42
    http://www.mathworks.cn/support/product/DM/installation/ver_current/?s_cid=pi_dc_pi_R2012b installing and Configuring Parallel Computing Toolbox and MATLAB Distributed Computing Server (R2012b)
  • TBB基础之parallel_for

    万次阅读 2007-11-15 23:24:00
    从现在开始我们要看一些TBB...首先看的也是最简单的parallel_for。我们还是先从一个例子开始看起:问题:对一个数组的每个元素施加一个操作Foo(...)串行化的版本: <!--Code highlighting produced by Actipro Cod

空空如也

1 2 3 4 5 ... 20
收藏数 188,941
精华内容 75,576
关键字:

parallel