2008-09-19 55 views
4

之前,我已經找到了「成本」在執行計劃中是相對執行時間的良好指標。爲什麼這個案件不同?我是否認爲執行計劃具有相關性?我能特別嘗試改進v_test性能嗎?解釋計劃成本還是執行時間

謝謝。

使用Oracle 10g我有下面定義

create or replace view v_test as 
    select distinct u.bo_id as bo_id, upper(trim(d.dept_id)) as dept_id 
    from 
     cust_bo_users u 
    join cust_bo_roles r on u.role_name=r.role_name 
    join cust_dept_roll_up_tbl d on 
          (r.region is null or trim(r.region)=trim(d.chrgback_reg)) and 
          (r.prod_id is null or trim(r.prod_id)=trim(d.prod_id)) and 
          (r.div_id is null or trim(r.div_id)=trim(d.div_id)) and 
          (r.clus_id is null or trim(r.clus_id)=trim(d.clus_id)) and 
          (r.prod_ln_id is null or trim(r.prod_ln_id)=trim(d.prod_ln_id)) and 
          (r.dept_id is null or trim(r.dept_id)=trim(d.dept_id)) 

定義與去除在ROLE_LEVEL柱依賴關係的目標,以取代以下視圖

 create or replace view v_bo_secured_detail 
    select distinct Q.BO_ID, Q.DEPT_ID 
    from (select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'REGION' and 
       trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'RG_PROD' and 
       trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and 
       trim(R.PROD_ID) = UPPER(trim(D.PROD_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'PROD' and 
       trim(R.PROD_ID) = UPPER(trim(D.PROD_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'DIV' and 
       trim(R.DIV_ID) = UPPER(trim(D.DIV_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'RG_DIV' and 
       trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and 
       trim(R.DIV_ID) = UPPER(trim(D.DIV_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'CLUS' and 
       trim(R.CLUS_ID) = UPPER(trim(D.CLUS_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'RG_CLUS' and 
       trim(R.REGION) = UPPER(trim(D.CHRGBACK_REG)) and 
       trim(R.CLUS_ID) = UPPER(trim(D.CLUS_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(D.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R, CUST_DEPT_ROLL_UP_TBL D 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'PROD_LN' and 
       trim(R.PROD_LN_ID) = UPPER(trim(D.PROD_LN_ID)) 
     union all 
     select U.BO_ID BO_ID, UPPER(trim(R.DEPT_ID)) DEPT_ID 
     from CUST_BO_USERS U, CUST_BO_ROLES R 
     where U.ROLE_NAME = R.ROLE_NAME and 
       R.ROLE_LEVEL = 'DEPT') Q 

一個簡單的查詢視圖。

爲v_test執行計劃比v_bo_secured_detail顯著下爲簡單

select * from <view> where bo_id='value' 

查詢。並且在真實世界查詢中使用時顯着更低

select CT_REPORT.RPT_KEY, 
     CT_REPORT_ENTRY.RPE_KEY, 
     CT_REPORT_ENTRY.CUSTOM16, 
     Exp_Sub_Type.value, 
     min(CT_REPORT_PAYMENT_CONF.PAY_DATE), 
     CT_REPORT.PAID_DATE 
    from CT_REPORT, 
     <VIEW> SD, 
     CT_REPORT_ENTRY, 
     CT_LIST_ITEM_LANG Exp_Sub_Type, 
     CT_REPORT_PAYMENT_CONF, 
     CT_STATUS_LANG Payment_Status 
    where (CT_REPORT_ENTRY.RPT_KEY = CT_REPORT.RPT_KEY) and 
     (Payment_Status.STAT_KEY = CT_REPORT.PAY_KEY) and 
     (Exp_Sub_Type.LI_KEY = CT_REPORT_ENTRY.CUSTOM9 and Exp_Sub_Type.LANG_CODE = 'en') and 
     (CT_REPORT.RPT_KEY = CT_REPORT_PAYMENT_CONF.RPT_KEY) and 
     (SD.BO_ID = 'JZHU9') and 
     (SD.DEPT_ID = UPPER(CT_REPORT_ENTRY.CUSTOM5)) and 
     (Payment_Status.name = 'Payment Confirmed' and (Payment_Status.LANG_CODE = 'en') and 
     CT_REPORT.PAID_DATE > to_date('01/01/2008', 'mm/dd/yyyy') and Exp_Sub_Type.value != 'Korea') 
    group by CT_REPORT.RPT_KEY, 
      CT_REPORT_ENTRY.RPE_KEY, 
      CT_REPORT_ENTRY.CUSTOM16, 
      Exp_Sub_Type.value, 
      CT_REPORT.PAID_DATE 

執行時間在WILDLY上是不同的。 v_test視圖花費15個小時,而v_bo_secured_detail花費幾秒鐘。


謝謝大家誰回答

這是一個要記住我。表達式的理論和數學符合基於硬件執行的現實的地方。哎喲。

回答

3

作爲the Oracle documentation says,成本可相對於一個特定的執行計劃的估計費用。在調整查詢時,成本相對於計算的特定執行計劃可能會發生變化。有時戲劇性。

與v_test的表現的問題是甲骨文想不出辦法來執行它不是執行嵌套循環等,每個cust_bo_roles,掃描所有cust_dept_roll_up_tbl的找到匹配。如果表的大小爲n和m,則需要n * m時間,這對於大型表格來說很慢。相比之下,v_bo_secured_detail被設置爲一系列查詢,每個查詢都可以通過其他一些機制來完成。 (Oracle有一個可能使用的數字,包括使用索引,動態構建哈希,或者對數據集進行排序併合並它們,這些操作都是O(n * log(n))或更好。)一小部分快速查詢速度很快。

那麼痛苦,因爲它是,如果你想這個查詢要快,那麼你需要打破它像以前那樣的查詢。

+0

你甚至不需要調整查詢。對索引/約束,機器負載或您無法控制的其他因素進行更改可能會導致計劃發生變化。 – EvilTeach 2011-04-14 21:20:08

0

低成本的一個方面 - 高執行時間是當你正在尋找大型數據集,它往往是整個做事散裝的更有效的,而如果你想快速的效果,它以儘可能少的工作獲得第一筆記錄的效率更高。在大型設備上工作時,重複執行能夠提供快速響應外觀的小操作不太可能會給出好的結果。

很多時候,當你想快速結果,USE_NL優化器提示將幫助。

此外,在測試圖,它是依靠IS NULL ... IS NULL不能使用索引也不可以使用函數,如在「表側」參數修剪。

4

執行計劃是理論,執行時間是現實。

該計劃顯示您的發動機如何去有關執行您的查詢,但某些步驟可能導致工作的過多的解決查詢。使用「x爲null或x = y」味道不好。如果r和d是大表,那麼您可能會遇到某種組合爆炸,並且請求通過大型磁盤塊列表無休止地循環。我想你在執行過程中會看到很多I/O。

另一方面,聯合選擇是短而甜的,因此可能會重用大量仍處於先前選擇狀態的磁盤塊,並且/或者您具有某種程度的並行性,因爲它們的讀取操作相同磁盤塊。

同樣使用trim()和upper()隨處看起來有點可疑。如果你的數據不太清楚,那麼可能需要定期進行一些定期清理,這樣你就可以說「x = y」並知道它是有效的。

更新:你問的技巧,以提高v_test。清理你的數據,使trim()和upper()不必要。他們可能會阻止使用索引(儘管這也會影響聯合選擇版本)。

如果你無法擺脫的「X爲空或X = Y」則Y = NVL(X,「不 - 不存在」)可能有更好的性能(假設「不 - 不存在」是一個「不可能發生」的id值)。

+0

+1 for一個執行計劃是理論,執行時間是現實。 – 2013-07-01 09:53:04

0

你有收集的所有底層表優化器統計?如果沒有他們,優化者的估計可能會隨着現實而變得瘋狂。

0

當你說「查詢計劃是較低的」,你的意思是較短的,或實際成本估計是低?替換視圖的一個明顯問題是,與cust_dept_roll_up_tbl的聯接使用幾乎完全不可索引的條件(索引可以滿足「是null」測試,但涉及調用每個參數的修剪不能),因此規劃器必須至少對錶進行一次,也可能是幾次連續的掃描以滿足查詢。

我不確定Oracle是否有此限制,但許多DB只能對每個包含的表執行單個索引掃描,因此即使清理了可加入索引的連接條件,也可能只能滿足一個條件與索引掃描,並且必須對餘數使用順序掃描。

0

要闡述有關成本位。

在Oracle 9/10g中,從而簡化了一下,成本由公式確定:

成本=(SrCount * SrTime + MbrCount * MbrTime + CpuCyclesCount * CpuCycleTime)/ SrTime

凡SrCount - 計數SrTime - 根據收集到的系統統計數據,MbrCount和MbrTime讀取一個單獨塊的平均時間,相應地多塊讀取相同(在全表掃描和索引快速全掃描期間使用),Cpu相關度量標準爲自身-explanatory ......並全部除以單塊讀取時間。