SQL调用服务器核心数(oracle 多线程)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL调用服务器核心数(oracle 多线程)相关的知识,希望对你有一定的参考价值。

参考技术A select    /*+parallel(t,25)+*/ 

一、Parallel

1. 用途

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

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

2. 语法

/*+parallel(table_short_name,cash_number)*/

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

开启parallel功能的语句是:

alter session enable parallel dml;

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

3. 实例说明

用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。

4. Parallel也可以用于多表

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

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

5. 小结

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

oracle 存储过程中多线程执行另一个存储过程

我想在一个存储过程A中,调用另一个存储过程B,由于B是用来将某个表的数据插入到另一个表中,用游标根据年份来做的,为了节省时间就需要多线程并发执行,也就是要并发的调用存储过程B,这个sql该怎么写呢,用 execute immediate 'exec procedure B(2014);exec procedure B(2015);' 这样的方式?不知道该怎么写这个sql,求教!

参考技术A --可以参考如下:
DECLARE
CURSRO C_T IS

SELECT 年份 FROM 表名;
BEGIN
FOR C_C IN C_T LOOP

BEGIN

PROCEDURE B(C_C.年份);

END;

END LOOP;
END;追问

这样就只是循环来顺序执行而已,我要的是并发,就像在pl/sql里面开多个 command窗口,或者开多个sqlplus窗口来执行一样,我记得好像在linux的shell脚本里面有这种写法,但是忘了咋写了!

追答

shell脚本里好像是:exec PROCEDURE B(年份1) & exec PROCEDURE B(年份2) & exec PROCEDURE B(年份3)
你试试。。。

以上是关于SQL调用服务器核心数(oracle 多线程)的主要内容,如果未能解决你的问题,请参考以下文章

oracle中在编写存储过程启动多线程的问题?

DELPHI下的多线程程序设计

VB.net可以多线程控制同一个窗体及其控件吗

多线程调用oracle存储过程是不是并发执行?

PHP开启异步多线程执行脚本

《Java核心技术》---- 多线程