drop table t; create table t as select 10 * mod (rownum-1, 2) x from dual connect by level <= 2000000; exec dbms_stats.gather_table_stats (user, 't', method_opt=>'for all columns size 1', estimate_percent=>100); select x, count(*) from t group by x; drop table pdf_calculator_results; create table pdf_calculator_results ( low_x number constraint pdf_calculator_results_pk primary key, card number, card_diff number, card_stnd_f number ); create or replace procedure pdf_calculator ( p_interval_width number, p_start number, p_stop number, p_num_samples int) is l_num_rows number; l_table_low t.x%type; l_table_high t.x%type; l_low_x t.x%type; l_our_min t.x%type; l_our_max t.x%type; l_cardinality number; l_cardinality_prev number; l_card_stnd_f number; begin delete from pdf_calculator_results; commit; select num_rows into l_num_rows from user_tables where table_name = 'T'; select min (endpoint_value), max (endpoint_value) into l_table_low, l_table_high from user_tab_histograms where table_name = 'T' and column_name = 'X'; for i in 0..p_num_samples-1 loop l_low_x := p_start + i/(p_num_samples-1) * (p_stop-p_start); l_our_min := l_low_x; l_our_max := l_low_x + p_interval_width; delete from plan_table; execute immediate 'explain plan for ' || 'select x from t' || ' where x > '|| l_our_min || ' and x < '|| l_our_max; select cardinality into l_cardinality from plan_table where operation = 'SELECT STATEMENT'; l_card_stnd_f := l_num_rows * (l_our_max-l_our_min) / (l_table_high - l_table_low); insert into pdf_calculator_results (low_x, card, card_stnd_f, card_diff) values (l_low_x, l_cardinality, l_card_stnd_f, l_cardinality - l_cardinality_prev); l_cardinality_prev := l_cardinality; end loop; commit; end pdf_calculator; / show errors; exec pdf_calculator (0.001, 0.1, 9.9-0.001, 101); col low_x form 99.999999 set echo off set feedback off spool range_sel_inf_02_data.dat select * from pdf_calculator_results order by low_x; spool off -- add a third distinct value insert /*+ append */ into t(x) select 6.1 from dual connect by level <= 1000000; commit; exec dbms_stats.gather_table_stats (user, 't', method_opt=>'for all columns size 1', estimate_percent=>100); exec pdf_calculator (0.001, 0.1, 9.9-0.001, 101); col low_x form 99.999999 set echo off set feedback off spool range_sel_inf_03_data.dat select * from pdf_calculator_results order by low_x; spool off -- add a fourth distinct value insert /*+ append */ into t(x) select 7.42 from dual connect by level <= 1000000; commit; exec dbms_stats.gather_table_stats (user, 't', method_opt=>'for all columns size 1', estimate_percent=>100); exec pdf_calculator (0.001, 0.1, 9.9-0.001, 101); col low_x form 99.999999 set echo off set feedback off spool range_sel_inf_04_data.dat select * from pdf_calculator_results order by low_x; spool off set autotrace traceonly explain select x from t where x > 0.1 and x < 0.1 + 0.001; select x from t where x > 0.1 and x < 0.1 + 2; select x from t where x > 0 and x < 0+0.00000000000000001; select x from t where x > 0 and x < 2.5; set autotrace off