select ? ?/*+parallel(t,25)+*/?
一齐饮、Parallel
1. 用途
強(qiáng)行啟用并行度來執(zhí)行當(dāng)前SQL捺信。這個在Oracle 9i之后的版本可以使用豪嚎,之前的版本現(xiàn)在沒有環(huán)境進(jìn)行測試。也就是說鹃彻,加上這個說明,可以強(qiáng)行啟用Oracle的多線程處理功能妻献。舉例的話蛛株,就像電腦裝了多核的CPU,但大多情況下都不會完全多核同時啟用(2核以上的比較明顯)育拨,使用parallel說明谨履,就會多核同時工作,來提高效率熬丧。
但本身啟動這個功能笋粟,也是要消耗資源與性能的。所有析蝴,一般都會在返回記錄數(shù)大于100萬時使用害捕,效果也會比較明顯。
2. 語法
/*+parallel(table_short_name,cash_number)*/
這個可以加到insert闷畸、delete尝盼、update、select的后面來使用(和rule的用法差不多佑菩,有機(jī)會再分享rule的用法)
開啟parallel功能的語句是:
alter session enable parallel dml;
這個語句是DML語句哦盾沫,如果在程序中用裁赠,用execute的方法打開。
3. 實(shí)例說明
用ERP中的transaction來說明下吧赴精。這個table記錄了所有的transaction组贺,而且每天數(shù)據(jù)量也算相對比較大的(根據(jù)企業(yè)自身業(yè)務(wù)量而定)。假設(shè)我們現(xiàn)在要查看對比去年一年當(dāng)中每月的進(jìn)祖娘、銷情況失尖,所以,一般都會寫成:
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執(zhí)行起來渐苏,如果transaction_date上面有加index的話掀潮,效率還算過的去;但如果沒有加index的話琼富,估計(jì)就會半個小時內(nèi)都執(zhí)行不出來仪吧。這是就可以在select 后面加上parallel說明。例如:
select /*+parallel(mmt,10)*/
to_char(transaction_date,'yyyymm') txn_month,
...
這樣的話鞠眉,會大大提高執(zhí)行效率薯鼠。如果要將檢索出來的結(jié)果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,
...
插入的機(jī)制和檢索機(jī)制差不多械蹋,所以出皇,在insert后面加parallel也會加速的。關(guān)于insert機(jī)制哗戈,這里暫不說了郊艘。
Parallel后面的數(shù)字,越大唯咬,執(zhí)行效率越高纱注。不過,貌似跟server的配置還有oracle的配置有關(guān)胆胰,增大到一定值狞贱,效果就不明顯了。所以蜀涨,一般用8,10,12,16的比較常見瞎嬉。我試過用30,發(fā)現(xiàn)和16的效果一樣勉盅。不過佑颇,數(shù)值越大,占用的資源也會相對增大的草娜。如果是在一些package挑胸、function or procedure中寫的話,還是不要寫那么大宰闰,免得占用太多資源被DBA開K茬贵。
4. Parallel也可以用于多表
多表的話簿透,就是在第一后面,加入其他的就可以了解藻。具體寫法如下:
/*+parallel(t,10) (b,10)*/
5. 小結(jié)
關(guān)于執(zhí)行效率老充,建議還是多按照index的方法來提高效果。Oracle有自帶的explan road的方法螟左,在執(zhí)行之前啡浊,先看下執(zhí)行計(jì)劃路線,對寫好的SQL tuned之后再執(zhí)行胶背。實(shí)在沒辦法了巷嚣,再用parallel方法。Parallel比較邪惡钳吟,對開發(fā)者而言廷粒,不是好東西,會養(yǎng)成不好習(xí)慣红且,導(dǎo)致很多bad SQL不會暴漏坝茎,SQL Tuning的能力得不到提升。我有見過某些人create table后暇番,從不create index或primary key嗤放,認(rèn)為寫SQL時加parallel就可以了。