Overview
When column expressions or multiple columns of one table are included in query predicates, optimizer sometimes gets inaccurate cardinality estimates, therefore, generates sub-optimal plans .
Oracle documentation provides the following description,
DBMS_STATS enables you to collect extended statistics, which are statistics that can improve cardinality estimates when multiple predicates exist on different columns of a table, or when predicates use expressions.
An extension is either a column group or an expression. Column group statistics can improve cardinality estimates when multiple columns from the same table occur together in a SQL statement. Expression statistics improves optimizer estimates when predicates use expressions, for example, built-in or user-defined functions.
The optimizer uses column group statistics for equality predicates, inlist predicates, and for estimating the GROUP BY cardinality.
create column group stats manually
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => 'sh',
TABNAME => 'customers',
METHOD_OPT => 'FOR ALL COLUMNS SIZE SKEWONLY ' ||
'FOR COLUMNS SIZE SKEWONLY (cust_state_province,country_id)' );
END;
/
create column group stats automatically
BEGIN
DBMS_STATS.SEED_COL_USAGE(
sqlset_name => null,
owner_name => null,
time_limit => 300);
END;
/
--
-- run explain plans for queries in the workload
--
SELECT DBMS_STATS.REPORT_COL_USAGE(
ownname => 'sh',
tabname => 'customers')
FROM DUAL
;
SELECT DBMS_STATS.CREATE_EXTENDED_STATS(
ownname => 'sh',
tabname => 'customers')
FROM DUAL;
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
ownname => 'sh',
tabname => 'customers');
END;
/
create column expression stats
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(
OWNNAME => 'sh',
TABNAME => 'customers',
METHOD_OPT => 'FOR ALL COLUMNS SIZE SKEWONLY ' ||
'FOR COLUMNS (LOWER(cust_state_province)) SIZE SKEWONLY'
);
END;
/
show extended stats
SELECT DBMS_STATS.SHOW_EXTENDED_STATS_NAME(
OWNNAME => 'sh',
TABNAME => 'customers',
EXTENSION => '(cust_state_province,country_id)') col_group_name
FROM DUAL
;
SELECT e.EXTENSION expression,
t.NUM_DISTINCT,
t.HISTOGRAM
FROM DBA_STAT_EXTENSIONS e,
DBA_TAB_COL_STATISTICS t
WHERE e.EXTENSION_NAME = t.COLUMN_NAME
AND e.TABLE_NAME = t.TABLE_NAME
;
drop extended stats
BEGIN
DBMS_STATS.DROP_EXTENDED_STATS(
OWNNAME => 'sh',
TABNAME => 'customers',
EXTENSION => '(cust_state_province, country_id)' );
END;
/
BEGIN
DBMS_STATS.DROP_EXTENDED_STATS(
OWNNAME => 'sh',
TABNAME => 'customers',
EXTENSION => '(LOWER(cust_state_province))'
);
END;
/