2019.02.21
OPTIMIZER ADAPTIVE CURSOR SHARING
目次
基本情報
パラメータ情報
Syntax : _OPTIMIZER_ADAPTIVE_CURSOR_SHARING 設定方法 : ・Parameter File ・ALTER SYSTEM SET “_OPTIMIZER_ADAPTIVE_CURSOR_SHARING” = TRUE ・ALTER SESSION SET “_OPTIMIZER_ADAPTIVE_CURSOR_SHARING” = TRUE
バージョンとデフォルト 9iR2 : - 10gR1: - 10gR2: - 11gR1: TRUE
説明
Adaptive Cursor Sharing機能を使用かどうかを指定します。既定値はTrueで、Oracleは常にAdaptive Cursor Sharing機能を使用します。
Adaptive Cursor Sharingと、文字通りの状況に合わせて柔軟にCursorをShareという意味です。この概念を実装するために、OracleはBind Sensitive Cursor、Bind Aware Cursorという新しい概念を導入しました。
Bind Sensitive Cursorとは、文字通りBind値に敏感なCursorという意味です。つまり、Bind値が変わると、それを敏感に処理するという意味です。 1)Equal条件では、条件節に書かれたカラムにHistogramがあり、2)Range条件である場合、OracleはこれをBind Senstive Cursorと呼びます。
Bind Aware Cursorとは、Bind Sensitive Cursorに入力されたBind値に基づいて実行計画が分化されたCursorを意味します。つまり、Bind Aware Cursorが作成されたのは、Bind変数の値に基づいてOracleが適切なChild Cursorを作成したことを意味します。
Adaptive Cursor Sharing技法を使用すると、Bind Peekingによって最初の実行時に実行計画が決定されても後に新しいBind変数の値が使用され、それに応じて実行計画を分化(新しいChild Cursor生成)します。したがってBind Peekingによる副作用が実質的にないことになります。ただし、条件節に書かれたカラムにHistogramがあり、Histogramの分布に基づいて実行計画に大きな差があると判断される条件が重要です。つまり、適切なHistogramなしに意味が有りません。
注意
Adaptive Cursor Sharingの使用例
- create objects drop table acs_table; create table acs_table(id int、name char(10)); create index acs_table_idx on acs_table(id); - generate skewed data insert into acs_table select 1、 'name' from all_objects where rownum <= 100000 insert into acs_table values(99、 'name'); commit; - gather statistics with histogram exec dbms_stats.gather_table_stats(user、「ACS_TABLE '、estimate_percent => 100、method_opt =>' FOR COLUMNS SIZE 2 ID」、cascade => true); - check histogram select * from dba_tab_histograms where table_name = 'ACS_TABLE'; - Bind query alter system flush shared_pool; var id number; - id == 1 - 各ステップごとに次のクエリの結果を確認 select sql_id、sql_text、is_bind_sensitive、is_bind_aware from v $ sql where sql_text like」select count(name)from acs_table% '; exec:id:= 1; select count(name)from acs_table where id =:id; - id == 99 exec:id:= 99; select count(name)from acs_table where id =:id; select count(name)from acs_table where id =:id; - id == 1 again exec:id:= 1; select count(name)from acs_table where id =:id; - check mismatch select * from v $ sql_shared_cursor where sql_id = '';