[英]Oracle 12c Subquery Factoring Inline View now has bad plan?
更新11/2
經過一些額外的故障排除后,我的團隊能夠將此Oracle錯誤直接與查詢停止工作前一天在12c
數據庫上進行的參數更改聯系起來。 在遇到與此數據庫12.1.02
的應用程序的一些性能問題后,我的團隊讓我們的DBA將OPTIMIZER_FEATURES_ENABLE
參數從12.1.02
為11.2.0.4
。 這解決了問題應用程序的性能問題,但導致了我上面描述的錯誤。 為了驗證,我已經能夠通過更改此參數在單獨的環境中復制相同的問題。 我的DBA已向Oracle提交了一張機票,以便對此進行查看。
作為一種解決方法,我能夠對我的查詢稍作更改,以便檢索預期的結果。 具體地講,我結合Subquery1
與Subquery2
和我在移動幾個謂詞Subquery1
從WHERE
子句到JOIN
(在那里它們更恰當地屬於)。 此更改編輯了我的執行計划(它的效率略低於之前列出的效率)但足以解決原始問題。
原帖
首先,讓我為這個問題中的任何模糊道歉,但我正在處理一個機密的金融系統,所以我被迫隱藏某些實施細節。
背景
我有一個很久以前投入生產的Oracle
查詢,它最近在從11g
升級到12c
之后不久產生了預期的結果。 對於我(以及我的生產支持團隊)的知識,這個查詢在此之前已經運行了一年多。
細節
查詢過於復雜且效率不高,但這在很大程度上是因為我正在處理非規范化表(歷史上以大型機為模型)和來自上游系統的較差數據輸入。 為了處理復雜的業務情況,我利用了多個級別的子查詢因子( WITH
語句),然后我的最終語句將兩個內聯視圖連接在一起。 沒有所有復雜謂詞的查詢的基本結構如下:
我有3個表Table1
, Table2
, Table3
。 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行 !
我已經審查了執行計划,但沒有任何事情發生在我身上:
問題
很明顯,我已經做了一些事情來混淆Oracle Optimizer,而更新的查詢計划正在拉回一個與我提交的查詢截然不同的查詢。 我最好的猜測是,所有這些臨時視圖都在同一個查詢中浮動,我讓Oracle混淆了在依賴它之前評估一些集合。
到目前為止,我一直無法找到圍繞WITH
語句的官方Oracle文檔,因此我從未對子查詢的評估順序充滿信心。 我確實注意到搜索SO( 現在找不到 )有人提到一個因子子查詢不能引用另一個因子查詢。 我以前從來不知道這是真的,但上面那個奇怪的輸出讓我想知道我之前是否只有這個查詢才幸運?
誰能解釋我所看到的行為? 我是否嘗試使用此查詢計划做一些明顯不正確的事情? 或者,是否有可能在11g和12c之間發生變化,這可以解釋為什么這個查詢的行為可能已經改變了?
這聽起來像Oracle中的“錯誤結果”錯誤。 這些錯誤通常非常特定於您使用的版本和功能。 您發布的查詢或執行計划沒有明顯錯誤。
您有兩種處理方式:
DUAL
。 此過程可能需要數小時。 最后,當您只剩下幾行代碼時,請在此處發布,查看Oracle支持或創建服務請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.