Server
Query plan
Also called explain.
Query plan is the database's chosen method for running a statement: which indexes to use, in what order to join tables, and how many rows it expects at each step. You read it with EXPLAIN.
How it is measured
Run `EXPLAIN` or, in Postgres, `EXPLAIN (ANALYZE, BUFFERS)` and read the node types, estimated versus actual rows, and time. Seq Scan, Index Scan, Nested Loop and Hash Join each tell a different story.
A large gap between estimated and actual rows means stale statistics, and the planner picked a method on bad information. Running ANALYZE refreshes them.
Worked example
A Postgres query lists orders for one customer on a table of 8 million rows. EXPLAIN ANALYZE shows a Seq Scan reading all 8 million rows and taking 2.6 seconds, with the planner's estimate of 4 matching rows against 11,200 actual.
After creating an index on customer_id and running ANALYZE, the plan shows an Index Scan of 11,200 rows in 38 ms. The query text never changed.
How it differs
A query plan is the route the database picks. A database index is a structure the route may use. The plan excludes the data structure, and the index excludes the decision to use it. Two identical queries can have different plans after the table grows, so the plan is what to check.
Common errors
Running EXPLAIN without ANALYZE and trusting estimates. Testing on a tiny dev table where a scan wins. Adding indexes and not checking they are used. Ignoring estimate-versus-actual gaps. Rewriting the query before reading the plan.
In practice
Take your slowest query from the slow log and run EXPLAIN ANALYZE on production-like data. Fix the biggest node first and run it again to confirm the plan changed.