Gblog

おもにTips

ヒストグラム、使った?

ある条件下でヒストグラムが使われるかどうか?という質問を受けた。

 

で、ヒストグラムが使われたかどうかを確認する方法ってあったけか?と調べてみたが、event 10053 以外は見つけられず。

そもそも、ヒストグラムは、取られていれば使われるもので、使われているかどうかを気にかける必要はなく、取られているかどうかを気をつければいい話だと思う。

 

・・・どうでもいい気がしてきた。

 

一応、10053 みてみたので参考まで。

 

準備、準備

grant dba to g identified by g;
conn g/g
create table test1 (id number, test_col number, mid number, dummy char(1000));
begin
for i in 1..10 loop
insert into test1 values (i,1,mod(i,3),'x');
commit;
end loop;
for j in 11..10000 loop
insert into test1 values (j,2,mod(j,3),'x');
commit;
end loop;
end;
/
alter table test1 add constraint test_pk primary key (id);
create index test_i1 on test1 (test_col);

create table test2 (mid number, dummy char(100));
insert into test2 values (0,'dog');
insert into test2 values (1,'cat');
insert into test2 values (2,'mike');
commit;

select count(*) from test1 where test_col=1;
exec dbms_stats.gather_table_stats('G','TEST1');
exec dbms_stats.gather_table_stats('G','TEST2');

 とってみる、とってみる

alter system flush shared_pool;
alter session set events '10053 level 1';
select * from test1,test2 where test_col=1 and test1.mid=test2.mid;
alter session set events '10053 off';

 結果、SINGLE TABLE ACCESS PATH ぐらいかな。。。

Access path analysis for TEST1
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for TEST1[TEST1]
Column (#2):
NewDensity:0.000500, OldDensity:0.000050 BktCnt:10000, PopBktCnt:10000, PopValCnt:2, NDV:2
Column (#2): TEST_COL(
AvgLen: 3 NDV: 2 Nulls: 0 Density: 0.000500 Min: 1 Max: 2
Histogram: Freq #Bkts: 2 UncompBkts: 10000 EndPtVals: 2
Table: TEST1 Alias: TEST1
Card: Original: 10000.000000 Rounded: 10 Computed: 10.00 Non Adjusted: 10.00
Access Path: TableScan
Cost: 199.48 Resp: 199.48 Degree: 0
Cost_io: 199.00 Cost_cpu: 12911046
Resp_io: 199.00 Resp_cpu: 12911046
Access Path: index (AllEqRange)
Index: TEST_I1
resc_io: 3.00 resc_cpu: 26314
ix_sel: 0.001000 ix_sel_with_filters: 0.001000
Cost: 3.00 Resp: 3.00 Degree: 1
Best:: AccessPath: IndexRange
Index: TEST_I1
Cost: 3.00 Degree: 1 Resp: 3.00 Card: 10.00 Bytes: 0

 

・・・逆か。

バインドピークをオフって使われないケースをみてみる。

alter session set "_optim_peek_user_binds"=false;
alter system flush shared_pool;
var bind1 number
exec :bind1 := 1;
alter session set events '10053 trace name context level 1,forever';
select * from test1,test2 where test_col=:bind1 and test1.mid=test2.mid;
alter session set events '10053 off';

 結果

Access path analysis for TEST1
***************************************
SINGLE TABLE ACCESS PATH
Single Table Cardinality Estimation for TEST1[TEST1]
Column (#2):
NewDensity:0.000500, OldDensity:0.000050 BktCnt:10000, PopBktCnt:10000, PopValCnt:2, NDV:2
Column (#2): TEST_COL(
AvgLen: 3 NDV: 2 Nulls: 0 Density: 0.000500 Min: 1 Max: 2
Histogram: Freq #Bkts: 2 UncompBkts: 10000 EndPtVals: 2
Table: TEST1 Alias: TEST1
Card: Original: 10000.000000 Rounded: 5000 Computed: 5000.00 Non Adjusted: 5000.00
Access Path: TableScan
Cost: 199.49 Resp: 199.49 Degree: 0
Cost_io: 199.00 Cost_cpu: 13110646
Resp_io: 199.00 Resp_cpu: 13110646
Access Path: index (AllEqRange)
Index: TEST_I1
resc_io: 725.00 resc_cpu: 7213894
ix_sel: 0.500000 ix_sel_with_filters: 0.500000
Cost: 725.27 Resp: 725.27 Degree: 1
Best:: AccessPath: TableScan
Cost: 199.49 Degree: 1 Resp: 199.49 Card: 5000.00 Bytes: 0 

 

ヒストグラムが使われたケースと使われていないケースで、ぱっとみ、まったく変わらない。両ケースとも Histogram は表示されている。

Cardinality (Card:) の計算結果などが違うので、そこから判断できる。

基本は、ヒストグラムが取られていて使用可能なコンディションにあれば、使用されていると考えていいと思う。

 

結論は、、、、、確認できないことはないけど面倒。

他に方法ないかな。。。見つけたら update します。