發現dblink如果很慢可以用這種方式加個/*+driving_site(xxx)*/,查詢很快
DBLINK HINT /*+ driving_site(org) */ 優化策略和思路
使用DBLINK遠程訪問數據庫的優化策略和思路:
策略:遠程訪問,網絡傳輸占很大部分,優化原則,減少網絡傳輸,將小的結果集拉到本地處理;
思路1:在遠端建立視圖;
思路2:使用DRIVING_SITE將數據拉到本地處理;
出現這種執行計划,主要原因是使用了db link,要想看到執行計划,可以加 hint,如:
/*+remote_mapping(db_link)*/或/*+driving_site(table_name)*/
用法: /*+driving_site(table_name)*/ : table_name 一般是大表!
在近期的一個數據庫查詢統計中,需要通過db_link跨庫進行表的關聯,其中A庫 中的某張擁有百萬以上數據的表與B庫 中的擁有千條記錄以上的表進行關聯。兩張表進行關聯的字段都建有索引。但在實際查詢中如果從B庫進行兩表的關聯卻會導致A庫中大表的全表掃描,查詢速度慢是次要的,關鍵是全表掃描會影響到A庫的正常運行。
通過對SQL語句的不斷調整、優化發現當兩表進行簡單的關聯查詢時,如果在select 后面采用"*"獲取所有數據時,查詢不會導致全表掃描,但在select 后面取具體字段時將會導致大表的全表掃描。
在簡單查詢的基礎上進行group分組將直接導致大表的全表掃描,在此種情況下,所有的語句優化技巧都將失效,因為索引無效,此時必須采取特殊的方法建立起關聯查詢的索引,強制指定在關聯過程中那一張表作為主要驅動表,那一張作為從表。在跨庫關聯查詢的過程中,因為表不在同一個數據庫中(同時在不同操作系統的服務器上)將導致關聯過程中將一張表的數據提取到另一個數據庫中進行關聯。此時問題出現,如果在關聯過程中將大表數據提取到小表所在庫進行運算將導致大表的全表掃描,整個運算過程將非常慢且影響A庫的正常運行。
最終解決全表掃描的辦法是,如果在B庫對不同數據庫的兩張大小表進行關聯時,通過driving_site強制指定主驅動表,即以所指定的表為主要表,將其它表作為從表提取到驅動表所在的庫進行關聯運算。具體語句如下:
select /*+driving_site(main)*/ a.*,b.* from A.a main@BigTableDB,B.b minor where main.id=minor.id and .......
這樣一來就可以避免大表所在庫的全表掃描,查詢速度將成級數級提高。
解釋:
當指定 /*+driving_site(main)*/ 時, oracle將會從minor表獲取全部數據到main表所在的數據庫來進行關聯運算.(索引起作用,速度快)
若指定 /*+driving_site(minor)*/ 時, oracle將會從main表獲取全部數據到minor表所在的數據庫來進行關聯運算.(索引失敗,全表掃描)
當然Oracle中有很多的關鍵字用於指定關聯查詢時的運算方法,等后面碰到具體應用實例實再作一一介紹。
引用:
DRIVING_SITE 作用和 ORDERED 類似。 DRIVING_SITE 通常在分布式查詢中使用。如果沒有這個提示, Oracle 會先從遠程點檢索,並將它們連接到本地站點中。通過使用 DRIVING_SITE ,我們可以先在本地進行檢索,將檢索后的數據發送到遠程節點進行連接
優化案例:
--create or replace view v_fasp_bjjzzfyszxqkfld2 as
select a.bdgmanagedivision,a.gnkm,acctdate,sum(a.yszb) yszb,sum(a.zjzfjh) zjzfjh ,sum(a.sqzfjh) sqzfjh,
sum(a.zjzfzc) zjzfzc,sum(a.sqzfzc) sqzfzc,sum(a.zjzfjhjy) zjzfjhjy,sum(a.sqzfjhjy) sqzfjhjy
from
(select /*+ driving_site(t) */ t.mb_code as bdgmanagedivision,substr(t.bs_code,1,3) gnkm,substr(t.create_date,1,4)||substr(t.create_date,6,2)||substr(t.create_date,9,2) as acctdate,
sum(t.budget_money) yszb,0 as jhje, 0 as zjzfjh,0 as sqzfjh,0 as zcje,0 as zjzfzc,0 as sqzfzc,
--0 as zcjezt,0 as zjzfzczt,0 as sqzfzczt,
0 as jhjy,0 as zjzfjhjy,0 as sqzfjhjy
--0 as jhkyje,0 as zjzfjhkyje,0 as sqzfjhkyje
from vw_budget_useable_voucher@chunyuan_link t
where t.en_code not like '910%'
--and t.pk_code like '1%'
and t.bo_code='001001'
and t.is_end =1
and t.is_valid=1
and t.bl_code like '001001%' and t.budget_vou_id is not null group by t.mb_code,substr(t.bs_code,1,3),
substr(t.create_date,1,4)||substr(t.create_date,6,2)||substr(t.create_date,9,2) --支付系統錄入指標
union all
select c.mb_code bdgmanagedivision,substr(c.bs_code,1,3) gnkm,plan_pay.acctdate,
0 as yszb,
nvl(plan_pay.zj_plan_money+plan_pay.sq_plan_money,0) jhje,
nvl(plan_pay.zj_plan_money,0) zjzfjh,nvl(plan_pay.sq_plan_money,0) sqzfjh,
nvl(plan_pay.zj_pay_money+plan_pay.sq_pay_Money,0) zcje,
nvl(plan_pay.zj_pay_money,0) zjzfzc,nvl(plan_pay.sq_pay_Money,0) sqzfzc,
nvl((plan_pay.zj_plan_money+plan_pay.sq_plan_money)-(plan_pay.zj_pay_money+plan_pay.sq_pay_Money),0) jhjy,
nvl(plan_pay.zj_plan_money,0)-nvl(plan_pay.zj_pay_money,0) zjzfjhjy,
nvl(plan_pay.sq_plan_money,0)-nvl(plan_pay.sq_pay_Money,0) sqzfjhjy
--20130507將gl_balance修改為(select sum_id,ccid from gl_balance_month_detail where set_month>0 group by sum_id,ccid) g
--解決計划額度ID號953119,6月份計划,新的額度,在GL_BALANCE表中還沒有對應的記錄。
from (select /*+ driving_site(c) */ sum_id,ccid,rcid from gl_balance_month_detail@chunyuan_link where set_month>0 group by sum_id,ccid,rcid) g,
vw_plan_voucher_nmg702@chunyuan_link c,
(select plan.toctrlid,plan.acctdate acctdate,
sum(zj_plan_money) zj_plan_money,
sum(sq_plan_money) sq_plan_money,
sum(zj_pay_money) zj_pay_money,
sum(sq_pay_Money) sq_pay_Money
from
--查詢計划數據
(select /*+ driving_site(p) */ p.toctrlid,substr(p.create_date,1,4)||substr(p.create_date,6,2)||substr(p.create_date,9,2) as acctdate,
sum(case when p.PK_CODE like '11%' then p.plan_money else 0 end) zj_plan_money,
sum(case when p.PK_CODE like '12%' then p.plan_money else 0 end) sq_plan_money
from vw_plan_voucher@chunyuan_link p ,gl_journal@chunyuan_link g
where p.ID=g.vou_id and p.is_valid=1 and g.is_end=1 and g.set_month>0 and g.billtype_code not like '1%'
and p.budget_vou_id is not null
group by p.toctrlid,substr(p.create_date,1,4)||substr(p.create_date,6,2)||substr(p.create_date,9,2)
) plan,
--查詢支出數據
(select /*+ driving_site(p) */ p.fromctrlid,substr(p.create_date,1,4)||substr(p.create_date,6,2)||substr(p.create_date,9,2) as acctdate,
sum(case when (p.PK_CODE like '11%' and p.clear_date is not null and g.is_end=1) then p.pay_money else 0 end) zj_pay_money,
sum(case when (p.PK_CODE like '12%' and p.clear_date is not null and g.is_end=1) then p.pay_money else 0 end) sq_pay_money
from vw_pay_voucher@chunyuan_link p ,gl_journal@chunyuan_link g
where p.ID=g.vou_id(+) and p.is_valid=1 and g.set_month>0 and g.billtype_code like '3%'
and p.budget_vou_id is not null
group by p.fromctrlid,substr(p.create_date,1,4)||substr(p.create_date,6,2)||substr(p.create_date,9,2)
) pay
where plan.toctrlid=pay.fromctrlid(+)
group by plan.toctrlid,plan.acctdate
) plan_pay
where g.sum_id=plan_pay.toctrlid and g.sum_id=c.toctrlid and g.rcid=c.rcid --and g.ccid=c.CCID and g.set_month>0
and (plan_pay.zj_pay_money<>'0' or plan_pay.sq_pay_Money<>'0' or plan_pay.zj_plan_money<>'0' or plan_pay.sq_plan_money<>'0')
and c.en_code not like '910%'
and c.bo_code='001001'
and c.bl_code like '001001%'
and exists(select /*+ driving_site(org) */ 1 from sys_user_org@chunyuan_link org where org.user_id = '7569' and org.org_id = c.MB_id) and 1=1
)a
group by a.bdgmanagedivision,a.gnkm,a.acctdate order by a.bdgmanagedivision,a.gnkm;