2012-09-06 6 views
8

Oracle 11gへのアップグレード後にOracleクエリを最適化する際に問題が発生しています。この問題が少し怒っています。分散クエリでバインドのピークが無効になっていますか?

簡単なテストケースを作成した後でさらに詳しい情報があるので、この質問は完全に編集されました。最初の質問はhttps://stackoverflow.com/revisions/12304320/1です。

この問題は、2つのテーブルを結合するときに、そのうちの1つが日付列にbetweenの条件を持つ場合、クエリがリモートテーブルに結合するとバインドのピークが発生しないという問題があります。

問題を再現するのに役立つテストケースです。最初に2つのソーステーブルを設定します。

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; 

その後でデータを実行するために、空のテーブルを作成します。最初は、その後dba_objectsから調達し、一部のデータが

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 
); 

30年遡る、月の最初のもの、日付のリストですto:

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

"_optim_peek_user_binds"パラメータをfalseに設定することを含むワークラウンドを持つバージョン> 11.1のバグがあります。これはオプティマイザに影響する可能性がありますが、正確にはわかりません。このパラメータがtrueまたはfalseに設定されているかどうかを確認することができます。このバグにより、ORA-3137エラーが発生します。 – Gisli

答えて

1

私はダイナミックサンプリングを混乱させるべきだと思います。それは11gで違って働くので、あなたの悩みの理由です。

関連する問題