Follow-up
I hadn't ever experimented SET STATISTICS
before, because there are only so many hours in a day. Inspired by Laurenz' answer, I've take a quick look. Here's a useful comment from the documentation:
https://www.postgresql.org/docs/current/planner-stats.html
The amount of information stored in
pg_statistic
byANALYZE
, in particular the maximum number of entries in themost_common_vals
and histogram_bounds arrays for each column, can be set on a column-by-column basis using theALTER TABLE SET STATISTICS
command, or globally by setting thedefault_statistics_target
configuration variable. The default limit is presently 100 entries. Raising the limit might allow more accurate planner estimates to be made, particularly for columns with irregular data distributions, at the price of consuming more space inpg_statistic
and slightly more time to compute the estimates. Conversely, a lower limit might be sufficient for columns with simple data distributions.
I have often got tables with a few common values and a lot of rare values. Or the other way around, so the right threshold will depend. For those who haven't used SET STATISTICS
, it lets you set the sampling rate as a target number of entries. The default is 100, so 1000 should be higher fidelity. Here's what that looks like:
ALTER TABLE assembly_prods
ALTER COLUMN assembly_id
SET STATISTICS 1000;
You can use SET STATISTICS
on a table or index. Here's an interesting piece on indexes:
https://akorotkov.github.io/blog/2017/05/31/alter-index-weird/
Note that the current documentation does list SET STATISTICS
on indexes.
So I tried out thresholds of 1, 10, 100, 1000, and 10,000 and got these results out of a table with 467,767 rows and 28,088 distinct values:
Target Estimate Difference Missing
1 13,657 14,431 51%
10 13,867 14,221 51%
100 13,759 14,329 51%
1,000 24,746 3,342 12%
10,000 28,088 0 0%
Obviously you can't draw any general conclusions from one case, but SET STATISTICS
looks pretty darn useful and I'll be glad to have it in the back of my mind. I'm tempted to raise the target a bit in general as I suspect it would help in many of the cases in our system.