Zunächst lege ich eine Tabelle mit einem sehr häufigen Wert (100 mit 990.000 Sätzen) und 100 relativ seltenen Werten an, die jeweils 100 mal vorkommen.
drop table test;
create table test
as
select case when rownum <= 10000 then mod(rownum, 100) else 100 end rn
, lpad('*', 100, '*') pad
from dual
connect by level <= 1000000;
exec DBMS_STATS.GATHER_TABLE_STATS(user, 'TEST', METHOD_OPT => 'FOR ALL COLUMNS SIZE 101')
select column_name
, NUM_BUCKETS
, NUM_DISTINCT
, HISTOGRAM
from user_tab_columns
where table_name = 'TEST'
and column_name = 'RN'
COLUMN_NAME NUM_BUCKETS NUM_DISTINCT HISTOGRAM
------------------------------ ----------- ------------ ----------
RN 39 101 FREQUENCY
Nun ja, näher an den Erwartungen, aber noch nicht ganz dran ... - wieso sind es nur 39 buckets, statt der 101, die ich verlangt hatte.
Vielleicht ein Effekt der Sortierung der Daten? Immerhin dürften die Werte <> 100 ja auf die ersten 10.000 Sätze beschränkt sein. Deshalb werfe ich meine Testmenge mit dbms_random etwas durcheinander:
drop table test;
create table test
as
select case when rownum <= 10000 then mod(rownum, 100) else 100 end rn
, lpad('*', 100, '*') pad
from dual
connect by level <= 1000000
order by dbms_random.value;
exec DBMS_STATS.GATHER_TABLE_STATS(user, 'TEST', METHOD_OPT => 'FOR ALL COLUMNS SIZE 101')
select column_name
, NUM_BUCKETS
, NUM_DISTINCT
, HISTOGRAM
from user_tab_columns
where table_name = 'TEST'
and column_name = 'RN';
COLUMN_NAME NUM_BUCKETS NUM_DISTINCT HISTOGRAM
------------------------------ ----------- ------------ ---------
RN 42 101 FREQUENCY
Näher dran, aber noch immer nicht das, was ich erwartet hatte. Vielleicht ist der Wert 100 immer noch zu predominant - immerhin betrifft er immer noch 99% der Werte. Gehen wir auf 90% herunter.
create table test
as
select case when rownum <= 100000 then mod(rownum, 100) else 100 end rn
, lpad('*', 100, '*') pad
from dual
connect by level <= 1000000;
exec DBMS_STATS.GATHER_TABLE_STATS(user, 'TEST', METHOD_OPT => 'FOR ALL COLUMNS SIZE 101')
select column_name
, NUM_BUCKETS
, NUM_DISTINCT
, HISTOGRAM
from user_tab_columns
where table_name = 'TEST'
and column_name = 'RN';
COLUMN_NAME NUM_BUCKETS NUM_DISTINCT HISTOGRAM
------------------------------ ----------- ------------ ---------
RN 100 101 FREQUENCY
select column_name
, ENDPOINT_VALUE
from user_histograms
where table_name = 'TEST'
and column_name = 'RN'
order by column_name;
COLUMN_NAME ENDPOINT_VALUE
------------------------------ --------------
RN 0
RN 1
RN 2
RN 3
RN 4
RN 5
RN 6
RN 7
RN 9
RN 10
RN 11
...
RN 98
RN 99
RN 100
100 Zeilen ausgewählt.
Das wäre dann also - endlich - das erwartete Resultat. Anscheinend ist der von Tom Kyte angesprochene predominant value bei 90% der Gesamtsätze nicht mehr so übermächtig, dass er die bucket-Anzahl reduzieren würde. Für heute reicht mir das.
Keine Kommentare:
Kommentar veröffentlichen