Why this problem matters
Stale or unrepresentative statistics can contribute to inaccurate row estimates by the optimizer. Updating every statistic merely because its date is old can create unnecessary compilation and maintenance work.
How to diagnose it
Review last_updated, rows, rows_sampled, and modification_counter together with object size. The same age can have different meaning for filtered, ascending-key, or very large tables.
The query lists statistics properties for user tables in the current database without modifying them. NULL or old dates are not automatic reasons for intervention without investigating plan impact.
SELECT OBJECT_SCHEMA_NAME(s.object_id) AS schema_name,
OBJECT_NAME(s.object_id) AS table_name,
s.name AS statistics_name,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.modification_counter
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
ORDER BY sp.modification_counter DESC, sp.last_updated;A safe solution approach
Choose update scope and sampling according to query behavior and the maintenance window. Verify AUTO_UPDATE_STATISTICS state and focus on objects supported by evidence.
Why continuous monitoring matters
Data-change rate is not constant, and bulk loads can age statistics quickly. moon can monitor change and query-performance trends and provide alerts through Slack, PagerDuty, or webhooks.
Frequently asked questions
Is every old statistic bad? Is a full scan always the best update method?
No, an old statistic can remain representative for an unchanged table. A full scan provides a more complete sample, but its cost and benefit must be measured on large objects.
How does moon help with this problem?
moon continuously observes SQL Server, PostgreSQL, and MongoDB signals, helping teams evaluate the problem as a trend instead of relying on a one-time check.