2016-01-06 65 views
0

此問題是相對於this question。 這是代碼我嘗試在12c中oracle - 相同的查詢,但在11g和12c中有不同的計劃

SELECT * FROM DMProgDate_00001 
    WHERE 1=1 
    AND ProgressOID IN ( 
    SELECT P.OID FROM (
     SELECT OID FROM (
     SELECT A.OID, ROWNUM as seqNum FROM (
      SELECT OID FROM DMProgress_00001 
      WHERE 1=1 
      AND Project = 'Moho' 
      AND Phase = 'Procurement' 
      AND Displine = 'Q340' 
      ORDER BY actCode 
     ) A 
      WHERE ROWNUM <= 20 
    ) WHERE seqNum > 0 
    ) P 
); 
  • 結果

    11克使用方法:在1秒

    12C:在8秒

這是查詢計劃在11g enter image description here

這是12C enter image description here

查詢計劃,當我拿出所有分頁代碼(如下圖所示)。 12c中的查詢速度足夠快,因爲11g需要分頁查詢。

SELECT * FROM DMProgDate_00001 
    WHERE 1=1 
    AND ProgressOID IN ( 
    SELECT P.OID FROM (
      SELECT OID FROM DMProgress_00001 
      WHERE 1=1 
      AND Project = 'Moho' 
      AND Phase = 'Procurement' 
      AND Displine = 'Q340' 
      ORDER BY actCode 
    ) P 
); 

這是我試圖OFFSET查詢(無分頁)計劃12C enter image description here

...鍵字(僅支持12C)和OPTIMIZER_FEATURES_ENABLE('11 .2.0.4' ),但與上述相同的結果(超過8秒)。

我們需要同時支持11g和12c,我知道一些繞道修復這個問題(在my pre-question),但不想保留它作爲相同的查詢代碼。有沒有可以解決這個問題的選項或設置?


加入查詢計劃作爲文本 (它們是不同的表名,但同一個表的結構和內容)

12c - over 3 sec 
Plan hash value: 3742986389 

----------------------------------------------------------------------------------------- 
| Id | Operation   | Name    | Rows | Bytes | Cost (%CPU)| Time  | 
----------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT  |     |  1 | 153 | 204 (0)| 00:00:01 | 
|* 1 | FILTER    |     |  |  |   |   | 
| 2 | TABLE ACCESS FULL | DMPROGDATE_00001 |  1 | 153 | 102 (0)| 00:00:01 | 
|* 3 | FILTER    |     |  |  |   |   | 
|* 4 | COUNT STOPKEY  |     |  |  |   |   | 
|* 5 |  TABLE ACCESS FULL| DMPROGRESS_00001 | 26 | 2288 | 102 (0)| 00:00:01 | 
----------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 
    1 - filter(EXISTS (<not feasible>) 
    3 - filter("OID"=:B1) 
    4 - filter(ROWNUM<=20) 
    5 - filter("PROJECT"='Moho' AND "PHASE"='Procurement' AND "DISPLINE"='Q340') 

Note 
    - dynamic statistics used: dynamic sampling (level=2) 
    - 1 Sql Plan Directive used for this statement 





11g - 0.01 sec 

Plan hash value: 833434956 
----------------------------------------------------------------------------------------- 
| Id | Operation   | Name    | Rows | Bytes | Cost (%CPU)| Time  | 
----------------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT  |     | 13 | 1157 | 57 (2)| 00:00:01 | 
|* 1 | HASH JOIN RIGHT SEMI|     | 13 | 1157 | 57 (2)| 00:00:01 | 
| 2 | VIEW    | VW_NSO_1   |  3 | 81 | 34 (0)| 00:00:01 | 
|* 3 | COUNT STOPKEY  |     |  |  |   |   | 
|* 4 |  TABLE ACCESS FULL| DMPROGRESS_00037 |  3 | 99 | 34 (0)| 00:00:01 | 
| 5 | TABLE ACCESS FULL | DMPROGDATE_00037 | 7388 | 447K| 22 (0)| 00:00:01 | 
----------------------------------------------------------------------------------------- 

Predicate Information (identified by operation id): 
--------------------------------------------------- 

    1 - access("PROGRESSOID"="OID") 
    3 - filter(ROWNUM<=20) 
    4 - filter("DISPLINE"='Q340' AND "PHASE"='Procurement' AND "PROJECT"='Moho') 
+0

是通過一個可視化工具生成的SQL?你有選擇重寫SQL嗎? (我問的原因是因爲有更有效的寫作方式)。 – Vampiro

+0

我正在使用Oracle SQL Delvoper,它支持通過選擇列表來更改數據庫連接。 –

+1

請運行'EXPLAIN PLAN for your_sql_query',然後運行11.2g和12c上的'SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)',然後將它們的結果**作爲純文本**複製並粘貼,而不是位圖。位圖非常難以閱讀。謝謝。 – krokodilko

回答

0

通過選擇可以極大地變化的兩個偶數之間環境優化選擇的執行計劃相同的版本,不只是11g和12c。這取決於很多因素,但主要是:

  • 表中的行數(?是他們ENVS相似)
  • 指標都存在(兩者都做DBS具有完全相同的索引?)
  • 什麼是否有表格和索引的統計信息,以及它們的最新狀態?如果不是最新的,請收集表格這些指標的統計數據。

如果您可以發佈這些詳細信息,我可以提供更有幫助的答案。

此外,代碼看起來像自動生成的,如果您可以隨意修改它們,基於細節,我們可以建議重寫的查詢和/或提示。

如果無法修改代碼,可以使用SQL計劃管理(SPM)強制執行計劃 - 從運行速度更快的數據庫導出並導入到其他數據庫。

UPDATE

使用SQL的這種簡化版本生成的計劃:

SELECT * FROM DMProgDate_00001 
WHERE ProgressOID IN ( 
    SELECT OID FROM DMProgress_00001 
    WHERE Project = 'Moho' 
     AND Phase = 'Procurement' 
     AND Displine = 'Q340' 
     AND ROWNUM <= 20 
    ORDER BY actCode 
); 
+0

我可以告訴他們1.它們在表格中的行數是相同的。 2.兩個表都有相同的索引。 3.不要認爲它是'最新'的意思。他們被製造出不同的時間(3個月前爲11g,2天前爲12c)。你想查看V $ INSTANCE表格信息嗎? –

+0

在SQLDeveloper中,右鍵單擊表並選擇收集統計信息。如果您沒有權限,請讓DBA來執行此操作。然後再次運行查詢,捕獲像@kordirko提到的計劃。 – Vampiro

相關問題