2012-09-06 61 views
8

我在升級到Oracle 11g後優化Oracle查詢時遇到問題,並且此問題開始讓我有點生氣。在分佈式查詢上禁用綁定窺視功能嗎?

請注意,這個問題現在已經完全編輯了,因爲在創建一個簡單的測試用例之後我有更多的信息。原始問題可以在這裏找到:https://stackoverflow.com/revisions/12304320/1

此問題是,如果連接兩個表(其中一個表在日期列中有一個between條件),如果查詢連接到遠程表,綁定窺視不會發生。

這是一個測試用例,幫助重現問題。首先設置兩個源表。首先是日期的列表,是在第一個月的,要追溯到30年前

create table mike_temp_etl_control 
as 
select 
    add_months(trunc(sysdate, 'MM'), 1-row_count) as reporting_date 
from (
    select level as row_count 
    from dual 
    connect by level < 360 
); 

然後一些數據從dba_objects來源:

create table mike_temp_dba_objects as 
select owner, object_name, subobject_name, object_id, created 
from dba_objects 
union all 
select owner, object_name, subobject_name, object_id, created 
from dba_objects; 

然後創建一個空表在運行數據到:

create table mike_temp_1 
as 
select 
    a.OWNER, 
    a.OBJECT_NAME, 
    a.SUBOBJECT_NAME, 
    a.OBJECT_ID, 
    a.CREATED, 
    b.REPORTING_DATE 
from 
    mike_temp_dba_objects a 
    join mike_temp_etl_control b on (
     b.reporting_date between add_months(a.created, -24) and a.created) 
    where 1=2; 

然後運行代碼。您可能需要創建更大版本的mike_temp_dba_objects以減慢查詢速度(或使用其他某種方法來獲取執行計劃)。在查詢運行時,我通過從不同的會話運行select * from table(dbms_xplan.display_cursor(sql_id => 'xxxxxxxxxxx'))來從會話中獲得執行計劃。

declare 
    pv_report_start_date date := date '2002-01-01'; 
    v_report_end_date date := date '2012-07-01'; 

begin 

    INSERT /*+ APPEND */ 
    INTO mike_temp_5 
    select 
    a.OWNER, 
    a.OBJECT_NAME, 
    a.SUBOBJECT_NAME, 
    a.OBJECT_ID, 
    a.CREATED, 
    b.REPORTING_DATE 
from 
    mike_temp_dba_objects a 
    join mike_temp_etl_control b on (
    b.reporting_date between add_months(a.created, -24) and a.created) 
    cross join [email protected] -- This line causes problems... 
where 
    b.reporting_date between add_months(pv_report_start_date, -12) and v_report_end_date; 

    rollback; 
end; 

通過查詢有遠程表,基數估計爲mike_temp_etl_control表是完全錯誤的,綁定窺測似乎並沒有發生。

對於上面的查詢執行計劃如下:

--------------------------------------------------------------------------------------- 
| Id | Operation    | Name     | Rows | Bytes | Cost (%CPU)| 
--------------------------------------------------------------------------------------- 
| 0 | INSERT STATEMENT   |      |  |  | 373 (100)| 
| 1 | LOAD AS SELECT   |      |  |  |   | 
|* 2 | FILTER     |      |  |  |   | 
| 3 | MERGE JOIN   |      |  5 | 655 | 373 (21)| 
| 4 |  SORT JOIN   |      | 1096 | 130K| 370 (20)| 
| 5 |  MERGE JOIN CARTESIAN|      | 1096 | 130K| 369 (20)| 
| 6 |  REMOTE    | DUAL     |  1 |  |  2 (0)| 
| 7 |  BUFFER SORT  |      | 1096 | 130K| 367 (20)| 
|* 8 |  TABLE ACCESS FULL | MIKE_TEMP_DBA_OBJECTS | 1096 | 130K| 367 (20)| 
|* 9 |  FILTER    |      |  |  |   | 
|* 10 |  SORT JOIN   |      |  2 | 18 |  3 (34)| 
|* 11 |  TABLE ACCESS FULL | MIKE_TEMP_ETL_CONTROL |  2 | 18 |  2 (0)| 
--------------------------------------------------------------------------------------- 

如果我然後與本地版本替換遠程dual我得到正確的基數(139代替2):

------------------------------------------------------------------------------------- 
| Id | Operation    | Name     | Rows | Bytes | Cost (%CPU)| 
------------------------------------------------------------------------------------- 
| 0 | INSERT STATEMENT  |      |  |  | 10682 (100)| 
| 1 | LOAD AS SELECT  |      |  |  |   | 
|* 2 | FILTER    |      |  |  |   | 
| 3 | MERGE JOIN   |      | 152K| 19M| 10682 (3)| 
| 4 |  SORT JOIN   |      | 438K| 51M| 10632 (2)| 
| 5 |  NESTED LOOPS  |      | 438K| 51M| 369 (20)| 
| 6 |  FAST DUAL  |      |  1 |  |  2 (0)| 
|* 7 |  TABLE ACCESS FULL| MIKE_TEMP_DBA_OBJECTS | 438K| 51M| 367 (20)| 
|* 8 |  FILTER    |      |  |  |   | 
|* 9 |  SORT JOIN   |      | 139 | 1251 |  3 (34)| 
|* 10 |  TABLE ACCESS FULL| MIKE_TEMP_ETL_CONTROL | 139 | 1251 |  2 (0)| 
------------------------------------------------------------------------------------- 

所以,我想問題是我怎樣才能得到正確的基數來估計?這是一個Oracle錯誤還是這是預期的行爲?

+0

爲了擺脫容易的東西,你重新收集[統計](http://docs.oracle.com/cd/E11882_01/server.112/e25494/general002.htm#ADMIN11525)在桌子上? – Ben

+0

是的,統計數據應該都是新鮮的。儘管明天會再次檢查。它是數據倉庫ETL負載的一部分,隨着它的發展,統計數據會聚到一切 –

+0

我知道在版本> 11.1中有一個錯誤,其中包含將「_optim_peek_user_binds」參數設置爲false的全面工作。這可以影響優化器,但我不知道如何。您可以檢查此參數設置爲true還是false,對於最高性能應該是正確的。該錯誤會導致ORA-3137錯誤。 – Gisli

回答

1

我認爲你應該搞砸動態採樣。它的工作方式與11g不同,因此可能是您的煩惱原因。