When a query is slow, the execution plan is the first thing to look at. It is SQL Server's own description of how it retrieved your data: which indexes it touched, in what order, how it joined tables and how many rows it expected at each step.
Estimated vs. actual plans
SQL Server can show you two kinds of plans:
- Estimated plan — produced by the optimizer without running the query. Useful for expensive queries you can't afford to run.
- Actual plan — the same plan, plus runtime statistics: actual row counts, number of executions, memory grants and warnings.
In SSMS, press Ctrl+M (include actual plan) before running the query, or Ctrl+L for an estimated plan. Pair it with I/O and timing statistics:
SET STATISTICS IO, TIME ON;
SELECT o.OrderID, o.OrderDate, c.CompanyName
FROM Sales.Orders AS o
JOIN Sales.Customers AS c ON c.CustomerID = o.CustomerID
WHERE o.OrderDate >= '2026-01-01';
The Messages tab now shows logical reads per table — the single most useful number for comparing two versions of a query.
Read plans right to left
Graphical plans flow from right to left: data starts at the operators on the right (index seeks and scans) and moves left toward the SELECT operator. Arrow thickness is proportional to the number of rows.
The operators that matter most
| Operator | What it means | Watch for |
|---|---|---|
| Index Seek | Navigates the B-tree directly to matching rows | Usually good |
