2013-10-13 48 views
2

我對Oracle 11數據庫有以下問題,雖然存在修復,但我想了解爲什麼它以這種方式進行反應。引起昂貴計劃的同義詞

我們有兩個模式:包含所有表,視圖,plsql,...的「dev」模式和包含dev對象同義詞的「app」模式,即語句不包含 模式名稱。

甲DEV-視圖引用表(select * from a a1 -> b -> a a2 union select * from c) ,其中有其用於選擇共同列,即,選擇 謂詞推入表「一」(300K行)和「b」(90K行)通過單獨的 索引訪問進行選擇,從而產生非常高效的計劃。

dev-fun是一個確定性的並行函數,它只是簡單地執行一些字符串操作,而不需要進一步的數據庫訪問 。

視圖上的選擇是這樣的:select * from view where common-column = fun(string) 該工程對開發模式符合市場預期,但如果這是在應用架構執行, 計劃變得相對昂貴,即fun(string)沒有被按下的結果, ,但是這些表是散列連接的,結果將被掃描以查找元素。

仍然在應用模式中,當我用函數結果替換fun(string)時,計劃再次變得便宜了 。

爲了解決這個問題,我複製在應用架構,而不是經由 引用它的同義詞的視圖,但在視/表變化的情況下,這意味着缺陷的潛在來源,因爲我們 通常不檢查應用程序架構... 對函數的調用仍然通過同義詞,並且視圖被按原樣複製,也就是 訪問基礎表的同義詞......並且計劃與它是在開發模式上執行 。

除了在所有基礎表上有選擇授予之外,我還嘗試授予表上的「查詢重寫」,「引用」和視圖上的「引用」。此外,我已經嘗試了該函數的authid選項。我不得不承認,我還沒有檢查row-level security,但我們沒有使用它們。

我還能檢查什麼?

oracle版本是11.0.2.2。打開甲骨文票據只是一個理論選項, ,因爲我們沒有直接的支持訪問權限,而且中間的層次更令人沮喪,因爲 與維護問題一起生活。

我知道,通常解釋計劃會有所幫助,但我們可以先嚐試解決方案,因爲 我懷疑是否有其他問題。

更新(二〇一三年十月十四日):

  • 暗示使用嵌套循環不起作用。
  • 基於函數的索引不被使用。

索引訪問:select * from v_vt_betreuer where vtid = 11803056;

enter image description here

散列訪問:select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);

enter image description here

複製視圖:即當視圖被複制到該應用架構

select * from v_vt_betreuer where vtid = VTNRVOLL_TO_VTID(11803056);

enter image description here

+0

讓我看看我是否理解:您有一個視圖將兩個表加入一個字段。你有這張表的別名。你有一個確定性的功能。如果您通過函數的結果在其自己的模式中查詢視圖,則計劃將採用索引,但如果您通過別名查詢相同的視圖,則不會。是嗎? –

+0

是的。聯合的第一部分是表「a」(兩次)與關聯表「b」的一級分層聯接。連接屬性不同於通用屬性(letz稱之爲vtid)。工會的另一張桌子非常小。如果別名與文字一起使用,則會再次使用索引。 – kiwiwings

+0

對不起,最後的評論部分是錯誤的。共同屬性用於連接 - 例如'選擇a1.vtid,a2。*從代理a1加入agency_employee b(b.vtid = a1.vtid)加入代理a2(a2.vtid = b.employee_vtid)' – kiwiwings

回答

1

嘗試創建索引這樣的:

CREATE INDEX func_index ON agency(fun(common_column)) 

這就是所謂的函數的索引。

我的猜測是,這種類型的查詢:

select a1.vtid, a2.* 
from agency a1 join agency_employee b on (b.vtid = a1.vtid) 
join agency a2 on (a2.vtid = b.employee_vtid) 

導致查詢優化器要做到這一點:

select a1.vtid, a2.* 
from agency a1 join agency_employee b on (func(b.vtid) = func(a1.vtid)) 
join agency a2 on (func(a2.vtid) = func(b.employee_vtid)) 

http://www.akadia.com/services/ora_function_based_index_2.html http://www.oracle-base.com/articles/8i/function-based-indexes.php

如果這也是沒有辦法,檢查您是否有行級安全:

http://docs.oracle.com/cd/E16655_01/server.121/e17609/tdpsg_ols.htm http://docs.oracle.com/cd/B19306_01/network.102/b14266/apdvcntx.htm#i1007410

+0

我很好奇這是否會改變計劃,因爲這個函數沒有用於連接......但是當然優化器有時是一些神奇的東西......明天當我回來工作時我會給出更新... – kiwiwings

+0

對不起,這種方法沒有奏效。在我添加了基於函數的索引(在webcc_vertreter(VTNRVOLL_TO_VTID(vtid))上創建索引abe_vertreter;在webcc_vt_betreuer(VTNRVOLL_TO_VTID(vtid))上創建索引abe_vertreter2;)...解釋計劃仍然保持不變。如果你很好奇,我已經附上了這個問題的計劃。 – kiwiwings

+0

+1用於抽取時間 – kiwiwings

0

你確定你是不是使用實際的功能模式NPS_WEBCC,而是一個代名詞在架構NPS_WEBCC_DEV的功能?

如果DEV架構不允許訪問APP架構中的對象,則無法推送條件。 您必須授予DEV模式的同義詞權限,因爲視圖位於DEV模式中。這就是將視圖複製到APP模式時開始工作的原因。

如果您在基於DEV函數的DEV架構中使用擴展統計信息,則可能會出現另一個問題,但需要在權限問題後對其進行排序。

您可以通過檢查以下查詢的解釋計劃來驗證它。應給予優化結果:

-- q1 
-- "v_vt_betreuer" is a synonym in app schema to a view in dev schema 
select * from v_vt_betreuer where vtid = NPS_WEBCC_DEV.VTNRVOLL_TO_VTID(11803056); 

-- q2 
select * from NPS_WEBCC_DEV.v_vt_betreuer where vtid=NPS_WEBCC_DEV.VTNRVOLL_TO_VTID(11803056); 

UPD 根據進一步調查最可能的問題是因爲MERGE補助缺少的觀點。它必須被授予視圖和其中使用的所有子視圖。

GRANT MERGE VIEW ON v_vt_betreuer TO NPS_WEBCC; 
+0

我確定在使用nps_webcc中的同義詞來訪問nps_webcc_dev中的函數。不知道是否可以授予同義詞,但我會在星期一嘗試。關於擴展統計,我不認爲我們使用這些直方圖,但也會檢查它。感謝你對我的支持。 – kiwiwings

+0

兩者都選擇導致昂貴的計劃。關於擴展的統計數據,我不想提供太多內部表格(即屏幕截圖)的表格,但正如您從上面的屏幕截圖中可以看到的那樣,公共列(vtid)具有唯一索引掃描訪問權限,但是兩個連接表中沒有vtid的直方圖。我會給它一個明天的直方圖... – kiwiwings

+0

**兩個選擇結果在昂貴的計劃** 這是我不希望q2的東西。您可以在DEV模式下登錄時檢查q2執行計劃嗎?我認爲這是一開始,它肯定是便宜的。如果q2在DEV下是便宜的,而在APP下是昂貴的,那麼它必須在贈款和政策上做些事情。 –