Guide · The plan, node by node
Buffers
Buffers is the line EXPLAIN (ANALYZE, BUFFERS) adds under each node, counting 8 kB pages.
shared hit is pages found in shared_buffers, PostgreSQL's own cache. shared read is
pages fetched from the operating system. dirtied and written are pages the query changed
and pages it wrote out to make room. temp read and temp written are the temp files a
Sort or Hash Join spilled to. The sample's Seq Scan on commerce.orders prints Buffers: shared hit=1204 read=181796.
Why it matters
Time varies with what else the server is doing. Buffers do not, which makes them the figure
to compare between two runs of a query. The ratio is read against hit. orders had
181,796 of its 183,000 pages come from outside shared_buffers, which is why the scan took
1,640 ms, and why it is faster the second time. Few rows and many buffers is an index on a
low-correlation column, a new page per row. Any temp above zero means work_mem ran out
somewhere below. written on a SELECT is not a bug: a read evicts dirty pages and sets
hint bits.
What to do
- Touch fewer pages before caching more. Reaching 206,880 rows through an index touches the pages those rows are on, not all 183,000. Will this index help? shows how to test one.
- If
readdominates on a table queried all day,shared_buffersmay be too small for the working set.ordersalone is 1.5 GB. - If
tempis above zero, find the node that spilled. Its finding names it.
In the Plan tab
The inspector's Pages section is the Buffers line drawn. Marker 3 is the one this page is
about.
The inspector for Seq Scan on orders, with Pages third from the top.
The inspector for Seq Scan on orders, with Pages third from the top.
Rowsis read against kept,2% kept. Rows and pages tell the same story from two sides: 12,000,000 rows is 183,000 pages.Rows per loopis actual against estimated,338× more. Pages are not estimated, so there is no ruler for them.Pagesisshared hitagainstshared read, drawn ascache 1,204againstdisk 182K,99% from disk. The table was not inshared_buffers, andtempwould appear beside them if the node had spilled.Indexes · ordersis the way to touch fewer pages: an index that starts withchannelwould reach the kept rows' pages and skip the rest.suggestedis that index, withTest. The costTestprints counts pages in units of one sequential read, so fewer pages touched is what a lower cost means.
all cached replaces the percentage when nothing came from disk. Dirtied and written pages
are not drawn. They are in Raw plan JSON.