2014-11-05 137 views
3

我的問題類似於To subselect or not to subselect?,但我想繼續使用兩個現有的視圖(因此我不想將子選擇直接移動到視圖邏輯中)。Subselect(而不是數字常量)惡化優化

慢速(1.5秒)

SELECT h.n 
FROM v_headers h 
WHERE h.n >= (select 3000 from dual); 

查詢是快速從直接子選擇使用值時:

SELECT h.n 
FROM v_headers h 
WHERE h.n >= 3000; 

多一點的細節:n不唯一的,它的值在0到4000之間;對於每個n存在大約50行。來自不同行的11個值沿着n旋轉成列。

有解決方案沒有提取視圖後面的選擇(或修改表)嗎?優化器提示也許?

首先是緩慢的,第二個是快一: enter image description here

LE:我已經簡化了查詢。


由於@ nop77svk,簡化的查詢工作得很快。更復雜的查詢不(還):

快速:

with xyz$ as (select 3986 as n from dual) 
SELECT h.hw_number 
    FROM xyz$ X 
    JOIN v_headers h 
    ON h.hw_number >= x.n 

慢(現在仍然有些簡化):

with xyz$ as ((SELECT nvl(MAX(n), 0) AS n 
      FROM (SELECT h.hw_number AS n, 
         Rank() OVER(ORDER BY h.hw_number DESC) rnk 
        FROM x_data h 
        GROUP BY h.hw_number) 
      WHERE rnk = 50)) 
SELECT h.hw_number 
    FROM xyz$ X 
    JOIN v_headers h 
    ON h.hw_number >= x.n; 

new query


關於視圖v_headers多一點的細節:

WITH s AS 
(
     SELECT a.n, 
       b.col_name, 
       a.value, 
       b.col_id 
     FROM qa_data a 
     JOIN column_def b 
     ON  b.col_id = a.col_id 
     WHERE b.master_dynamic_data = 'M') 
SELECT "n","c1","c2","c3","c4","c4","c5","c6","c7","c8","c9","c10" 
FROM  s PIVOT(Max(value) 
       keep(dense_rank first ORDER BY col_id) FOR col_name IN (
        'c1' c1, 
        'c2' c2, 
        'c3' c3, 
        'c4' c4, 
        'c5' c5, 
        'c6' c6, 
        'c7' c7, 
        'c8' c8, 
        'c9' c9, 
        'c10' c10, 
        'c11' c11)) 

COLUMN_DEF

  • 72行
  • 57行與master_dynamic_data = 'M'
  • column_def.col_id:獨特1..100(帶缺口)
  • column_def.col_name:C1,C2,C3,...(20個字符實際上而不是 'CX')

qa_data:

  • 450K行
  • 每個qa_data.n線的平均數目爲112行。 (n是從1到4000)
  • qa_data的平均長度。值是18個字符
+0

兩個發佈的查詢都是相同的。故意? – nop77svk 2014-11-05 14:07:40

+0

@ nop77svk太多打開的窗口...謝謝。 – 2014-11-05 14:19:37

+0

儘管我嘗試過,但似乎我無法幫到你。我根本無法將謂詞推向觀點,無論我如何嘗試。 – nop77svk 2014-11-06 10:35:55

回答

1

在簡化版本...

SELECT --+ leading(X) use_hash(H) 
    H.n 
FROM (select 3000 as n from dual) X 
    JOIN v_headers H 
     ON H.n >= X.n 
; 

...的>= 3000謂詞正確地解析爲訪問謂語,這將導致Exadata存儲索引一命嗚呼

但是,在完整版本中,必須強制將謂詞傳播到內部視圖,這似乎不會發生。對測試設置的快速檢查表明,將這樣的謂詞(對於計算值而不是常量值)傳播給連接視圖將運行正常,但將謂詞傳播至樞軸連接視圖則不會。

當使用預先計算n而不是使用內聯視圖的值的確定性函數時謂詞不會被推到pivoted join視圖(在12.1.0.2上嘗試)時,同樣的情況是成立的。

看到10053事件跟蹤文件瞭解發生了什麼會很有趣。 (讀者的作業; ;-))

+0

感謝您的提議,但這是不可能的。我意識到,你無法快速測試,這是令人沮喪的。我將嘗試創建另一個完整的查詢/視圖,或者我將編寫一個PL SQL函數。再次感謝您的時間和知識! – 2014-11-06 08:35:09

+0

順便說一句,你使用的是哪個版本的Oracle DB? – nop77svk 2014-11-06 08:35:36

+0

11g企業版,11.2.0.4.0 – 2014-11-06 08:36:51