bind peeking--バインド変数の覗き込み
5552 ワード
バインド変数の覗き込みとは、oracleがSQL文を初めて解析したとき(つまり、このSQLがshared poolに初めて入力されたとき)に、入力したバインド変数の値をSQL文に持ち込み、あなたの字面値を参考にしてSQLがどれだけのレコードを返すかを推測し、最適化された実行計画を得ることです.その後、後で同じSQL文を再度実行するときは、入力したバインド変数の値を考慮せずに、最初に生成したバインド変数を直接取り出します.しかし、残念なことに、バインド変数を使用してカーソルとSQLの最適化を共有することは、2つの矛盾した目標です.Oracleでは、バインド変数を使用する前提として、oracleがほとんどのカラムのデータが均一に分散されていると考えています.したがって、最初のバインド変数の値を用いて得られる実行計画は、そのバインド変数の他の値に適用されることが多い.最初に入力されたバインド変数の値がデータ全体の割合にちょうど高い場合、テーブル全体のスキャンの実行計画が発生することは明らかです.その後に入力されたバインド変数の値がデータ量全体に占める割合が低い場合は、インデックススキャンを実行するほうがいいですが、バインド変数を使用しているため、oracleはバインド変数の値を見るのではなく、テーブルスキャンの実行計画を直接持って使用します.このとき,バインド変数を用いたため,カーソル共有によりCPUを節約する目的を達成したが,SQLの実行計画は最適化されていない.
じっけん
OPT_PARAM('_optim_peek_user_binds' 'false')
select /*+opt_param('_optim_peek_user_binds', 'false')*/ id,name from test1 where id=:fid; 11 G-ACSは、異なるバインド変数の値に基づいて同じSQLに対してより優れた実行計画を生成し、data skewの異なる状況に適応する.
詳細については、http://blog.itpub.net/15415488/viewspace-621535
じっけん
SCOTT@ fyl>create table t1 as select * from dba_objects;
SCOTT@ fyl>create index t1_id on t1(object_id);
SCOTT@ fyl>execute dbms_stats.gather_table_stats(ownname => 'SCOTT',tabname => 'T1' ,method_opt => 'for all indexed columns' ,cascade => true);
SCOTT@ fyl>var id number;
SCOTT@ fyl>exec :id :=100;
SCOTT@ fyl>set autotrace traceonly;
SCOTT@ fyl>select * from t1 where object_id<:id;
98 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2288890262
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3272 | 313K| 17 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 3272 | 313K| 17 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_ID | 589 | | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"<TO_NUMBER(:ID))
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
18 consistent gets
0 physical reads
0 redo size
10120 bytes sent via SQL*Net to client
485 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
98 rows processed
SCOTT@ fyl>exec :id :=50000;
SCOTT@ fyl>select * from t1 where object_id<:id;
49588 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 2288890262
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3272 | 313K| 17 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 3272 | 313K| 17 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | T1_ID | 589 | | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("OBJECT_ID"<TO_NUMBER(:ID))
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
7887 consistent gets
0 physical reads
0 redo size
5495043 bytes sent via SQL*Net to client
36774 bytes received via SQL*Net from client
3307 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49588 rows processed
,Plan hash value: 2288890262
SCOTT@ fyl>select /*+full(t1) */ * from t1 where object_id<:50000;
49588 rows selected.
Execution Plan
----------------------------------------------------------
Plan hash value: 3617692013
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3272 | 313K| 262 (1)| 00:00:04 |
|* 1 | TABLE ACCESS FULL| T1 | 3272 | 313K| 262 (1)| 00:00:04 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("OBJECT_ID"<TO_NUMBER(:ID))
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
4198 consistent gets
0 physical reads
0 redo size
2349310 bytes sent via SQL*Net to client
36774 bytes received via SQL*Net from client
3307 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
49588 rows processed
object_id<:50000-- 7887 consistent gets
object_id<:50000-- 4198 consistent gets
OPT_PARAM('_optim_peek_user_binds' 'false')
select /*+opt_param('_optim_peek_user_binds', 'false')*/ id,name from test1 where id=:fid; 11 G-ACSは、異なるバインド変数の値に基づいて同じSQLに対してより優れた実行計画を生成し、data skewの異なる状況に適応する.
詳細については、http://blog.itpub.net/15415488/viewspace-621535