簡體   English   中英

Oracle 12c Subquery Factoring Inline View現在有不好的計划嗎?

[英]Oracle 12c Subquery Factoring Inline View now has bad plan?

更新11/2

經過一些額外的故障排除后,我的團隊能夠將此Oracle錯誤直接與查詢停止工作前一天在12c數據庫上進行的參數更改聯系起來。 在遇到與此數據庫12.1.02的應用程序的一些性能問題后,我的團隊讓我們的DBA將OPTIMIZER_FEATURES_ENABLE參數從12.1.0211.2.0.4 這解決了問題應用程序的性能問題,但導致了我上面描述的錯誤。 為了驗證,我已經能夠通過更改此參數在單獨的環境中復制相同的問題。 我的DBA已向Oracle提交了一張機票,以便對此進行查看。

作為一種解決方法,我能夠對我的查詢稍作更改,以便檢索預期的結果。 具體地講,我結合Subquery1Subquery2和我在移動幾個謂詞Subquery1WHERE子句到JOIN (在那里它們更恰當地屬於)。 此更改編輯了我的執行計划(它的效率略低於之前列出的效率)但足以解決原始問題。


原帖

首先,讓我為這個問題中的任何模糊道歉,但我正在處理一個機密的金融系統,所以我被迫隱藏某些實施細節。

背景

我有一個很久以前投入生產的Oracle查詢,它最近在從11g升級到12c之后不久產生了預期的結果。 對於我(以及我的生產支持團隊)的知識,這個查詢在此之前已經運行了一年多。

細節

查詢過於復雜且效率不高,但這在很大程度上是因為我正在處理非規范化表(歷史上以大型機為模型)和來自上游系統的較差數據輸入。 為了處理復雜的業務情況,我利用了多個級別的子查詢因子( WITH語句),然后我的最終語句將兩個內聯視圖連接在一起。 沒有所有復雜謂詞的查詢的基本結構如下:

我有3個表Table1Table2Table3 Table1是由表Table2的記錄組成的處理表。

--This grabs a subset from Table1
WITH Subquery1 as (
   SELECT FROM Table1),

--This eliminates certain records from the first subset based on sister records 
--from the original source table 
Subquery2 as (
   SELECT FROM Subquery1
   WHERE NOT EXISTS FROM (SELECT from Table2)),

--This ties the records from Subquery2 to Table3
Subquery3 as (
   SELECT FROM Table3
   JOIN (SELECT Max(Date) FROM Table3)
   JOIN Subquery2)

--This final query evaluates subquery3 in two different ways and 
--only takes those records which fit the criteria items from both sets
SELECT FROM 
(SELECT FROM Subquery3)             -- Call this Inline View A
JOIN (SELECT FROM Subquery3)        -- Call this Inline View B

最后的查詢非常基本:

   SELECT A.Group_No, B.Sub_Group, B.Key, B.Lob               
   FROM   (SELECT Group_No, Lob, COUNT(Sub_Group) 
           FROM   Subquery3 
           GROUP BY Group_No, Lob
           HAVING COUNT(Sub_Group) = 1) A 
   JOIN (SELECT Group_No, Sub_Group, Key, Lob
         FROM   Subquery3 
         WHERE  Sub_Group LIKE '0000%') B 
   ON A.Group_No = B.Group_No
   AND A.Lob = B.Lob

問題

如果我編輯最終查詢以刪除第二個內聯視圖並評估A內聯視圖的輸出,我將返回0返回的行 我手動評估了每個子查詢的記錄,並確認這是預期的結果。

同樣,如果我編輯最終查詢以僅生成“B”內聯視圖的輸出,那么我將返回6個返回的行 我再次手動評估了數據,這與預期完全一致。

現在,當將這兩個子集(內聯視圖A和內聯視圖B )連接在一起時,我希望最終查詢結果為0行(因為完整集和空集之間的內部連接不會產生匹配)。 但是,當我如上所述使用內部聯接運行整個查詢時, 我將返回1158行

我已經審查了執行計划,但沒有任何事情發生在我身上:

執行計划1 執行計划2

問題

很明顯,我已經做了一些事情來混淆Oracle Optimizer,而更新的查詢計划正在拉回一個與我提交的查詢截然不同的查詢。 我最好的猜測是,所有這些臨時視圖都在同一個查詢中浮動,我讓Oracle混淆了在依賴它之前評估一些集合。

到目前為止,我一直無法找到圍繞WITH語句的官方Oracle文檔,因此我從未對子查詢的評估順序充滿信心。 我確實注意到搜索SO( 現在找不到 )有人提到一個因子子查詢不能引用另一個因子查詢。 我以前從來不知道這是真的,但上面那個奇怪的輸出讓我想知道我之前是否只有這個查詢才幸運?

誰能解釋我所看到的行為? 我是否嘗試使用此查詢計划做一些明顯不正確的事情? 或者,是否有可能在11g和12c之間發生變化,這可以解釋為什么這個查詢的行為可能已經改變了?

這聽起來像Oracle中的“錯誤結果”錯誤。 這些錯誤通常非常特定於您使用的版本和功能。 您發布的查詢或執行計划沒有明顯錯誤。

您有兩種處理方式:

  1. 嘗試找到准確的錯誤。 你正在使用常見的表表達式看起來很好。 在極少數情況下,您的查詢在技術上無效,您在一個版本中獲得“幸運”並且它可以正常運行,並且在升級時它失敗。 但是當發生這種情況時,新版本通常會拋出錯誤,而不會返回錯誤的結果。 可能有一些非常奇怪的,特定的功能組合正在引起問題。 要找到真正的問題,您需要大規模簡化查詢,直到您可以進行盡可能小的更改並看到問題出現和消失。 您還需要刪除所有對象並僅使用DUAL 此過程可能需要數小時。 最后,當您只剩下幾行代碼時,請在此處發布,查看Oracle支持或創建服務請求。
  2. 避免這個bug。 即使您完成上述步驟,也可能無法解決問題。 有時,最好的解決方法是采取不同的做法。 能夠深入了解每個問題但你並不總是有時間。 相反,嘗試以語法不同但邏輯上等效的方式重寫查詢。 刪除部分或全部公用表表達式,甚至可能重復一些SQL。 但請務必發表評論,警告未來的程序員,為什么你會以一種奇怪的方式做事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM