We use the following to refresh statistics for all tables in a given schema:
exec dbms_stats.gather_schema_stats(ownname => 'some_schema', estimate_percent => dbms_stats.auto_sample_size, cascade => true, method_opt => 'FOR ALL COLUMNS SIZE AUTO', degree => 12);
This however, sets row-counts for our materialized views to zero and has the unwanted side effect of causing inefficient query plans for queries against materialized views. We work around this by gathering table stats against the specific mviews after the schema stats have run.
My question is: can I change the parameters to gather_schema_stats in any way that will cause mview row-counts not to be set to zero?
You can’t tell
GATHER_SCHEMA_STATSto exclude certain objects. You could do aGATHER STALEto gather statistics only on the objects where statistics are stale but it is entirely possible that would include your materialized views. A few ways to work around that1) Use the
LOCK_TABLE_STATSprocedure to lock the statistics on your materialized views. That will preventGATHER_SCHEMA_STATSfrom gathering statistics on those objects until you call theUNLOCK_TABLE_STATSprocedure (presumably as part of the process that refreshes the materialized view statistics periodically).2) Use the
EXPORT_TABLE_STATSprocedure to save the statistics for the materialized views before gathering schema statistics and then callRESTORE_TABLE_STATSafter theGATHER_SCHEMA_STATScall completes to put the materialized view statistics back.3) Don’t use
GATHER_SCHEMA_STATS. CallGATHER_TABLE_STATSin a loop where you exclude whatever objects you want. Something like