Chapter Nine · The Planner and EXPLAIN
The Planner and EXPLAIN
Postgres does not follow rules when it runs a query. It prices every plan it can think of and executes the cheapest one, and the price is computed from statistics that describe the table as it was the last time anyone looked. Six topics on reading that arithmetic — and on the first Saturday of the month, when the arithmetic is wrong by five orders of magnitude.
Chapter 8 built Cartwheel's indexes. This chapter is about the component that decides whether to use them, and it works differently from what most engineers assume. There is no rule saying "an equality predicate on an indexed column uses the index". There is an arithmetic: for every way of getting the rows, Postgres estimates how many rows come out and multiplies that by a set of per-page and per-tuple constants, then runs whichever plan came out cheapest. Change the estimate and the plan changes. That is the whole mechanism, and once it is in your head, "the planner ignored my index" stops being a complaint and becomes a question with a findable answer.
Which matters here because the estimate is the part that breaks. Statistics are a 30,000-row sample of a 40-million-row table, refreshed when autovacuum decides enough has changed. A histogram describes the data that existed when it was built, and says almost nothing about rows inserted since. On the first Saturday of each month, a query that has run in 40 ms for four weeks runs in 6 seconds, for about twenty minutes, and then recovers without anyone touching it. Nothing was deployed. No host is short of CPU. Restarting the API makes it look fixed, which is why it survived three months of investigation. The plan is the evidence, and by the end of this chapter you will be able to read it off the page.
The six topics build in one direction. First the shape of a plan and the four numbers on every node, then EXPLAIN (ANALYZE) and the estimated-versus-actual comparison that turns reading into diagnosing. Then the five ways Postgres gets rows off disk and the three ways it joins them, because those are the choices the estimate is buying. Then the statistics themselves — what ANALYZE collects, how a range predicate is priced from a histogram, and what happens to a value that lies past the last bucket. The final topic is the diagnostic procedure, and it ends by naming Cartwheel's Saturday, showing the two plans side by side, and fixing it.
Topics in This Chapter
LIMIT can select an entirely different plan, and the difference between an Index Cond and a Filter.loops multiplication trap, what a disk spill looks like, and why ANALYZE on a DELETE deletes.Gather on top.pg_stats. Independence assumptions, extended statistics, and the ascending-key problem.