Free concept playground · no account

Query, Meet Consequence

Write SQL, then see why 'fast enough' was a full scan.

Query, Meet Consequence

AvailableFree

Point a query at a table, then read the plan. You’re judged on what the database actually does — rows scanned vs rows returned — not on whether it felt fast.

Table size
Index on the WHERE column
Joined tables
Full table scanFAST
  • Scanned 1M
  • Returned 50K
1Mrows scanned50Krows returned1Mcost units10 msest. latency
What the planner is really doingscanned rows, not wall-clock, is the tell

This query is a full table scan: it reads 1,000,000 rows to return 50,000, at an estimated 10 ms (fast). Fast today, but this is a full table scan — it reads every row. Index the WHERE column now so it stays fast as the table grows.

“It returns in a few milliseconds” hides the number that matters: rows scanned. A full scan that’s quick on a small table reads every single row, so its cost grows with the table — fast today, slow at 10× the data. An index seek jumps straight to the matching rows, so it stays fast as the table grows. Fast because it’s correct beats fast by luck.

Was this playground useful?

Query, meet consequence

Point a SQL query at a table and watch what the database actually does. You pick the table size, whether the filtered column is indexed, how many rows the WHERE clause matches, and how many tables you join — and the plan comes back: rows scanned versus rows returned, a cost figure, an estimated latency, and a verdict. The reveal is the gap between fast today and fast because it's correct: a query that returns in milliseconds can still be a full table scan quietly waiting to fall over as the data grows. Runs entirely in your browser (0 uploads, works offline).

How to use it

  1. Choose a table size (10K → 100M rows) and set how many rows the filter matches with the selectivity slider.
  2. Toggle Index on the WHERE column on and off, and add up to three joined tables.
  3. Read the plan: the bar shows how much of the table was scanned versus returned; the stats show rows scanned, cost units and estimated latency; the verdict reads fast / ok / slow.
  4. Watch what happens when you bump the same query from 1M to 100M rows — a full scan that felt fast tips into slow, while an index seek stays fast.

What this clears up (the fundamentals)

  • Rows scanned, not wall-clock, is the tell. A query that returns quickly can still read every row in the table. Latency hides the work; the scan count exposes it.
  • A full table scan's cost grows with the table. Fast on 10K rows means nothing — the same scan on 100M rows reads 10,000× more, so it degrades exactly when your data succeeds.
  • An index seek jumps straight to matching rows. With an index on the filtered column the planner reads only the rows it returns, so cost tracks the result size, not the table size.
  • Joins multiply the work. Each joined table inflates the cost of whatever rows you're already scanning — a full scan under a join is expensive twice over.
  • Selectivity decides whether an index even helps. If the WHERE clause matches most of the table, a seek stops being cheap; a very selective filter is where an index pays off most.

Where it's used

A Data-track drill for the "Data Before Models" lesson — the fastest way to build the instinct for reading a query plan instead of trusting a stopwatch. It's a miatz build-lab concept playable: play the widget here, then learn to build the real thing (a live EXPLAIN flame graph over a seeded database) in the lab.

FAQ

What's the difference between a full scan and an index seek?

A full table scan reads every row and checks each against the WHERE clause; an index seek uses an index to jump straight to the matching rows without touching the rest. Both return the same result — the seek just does far less work.

Why does a "fast" query get flagged?

Because speed on today's data isn't the same as scaling. The tool marks a full scan even when its latency is low, because that same scan reads every row: 10× the table means 10× the work. The verdict tells you it's quick now; the scan type tells you why it won't stay that way.

What is selectivity?

The fraction of rows the filter matches. A very selective filter (say 0.1%) returns few rows and is where an index helps most; a low-selectivity filter that matches most of the table gets little benefit from an index because you're reading most of it anyway.

Is anything uploaded?

No. The table size, index toggle, selectivity, joins and the whole plan are computed in your browser — nothing is transmitted or stored. Turn off your Wi-Fi and it still works.

Limits

A teaching model, not a real query planner. It uses a simple cost model (rows scanned, inflated by joins) and a rough latency estimate; a production optimizer weighs statistics, index depth, cache state, join algorithms and hardware. Use it to build the "read the scan, not the clock" instinct, then confirm against a real EXPLAIN ANALYZE on your own database.

Related

Part of the Demystify Playgrounds. Explore the rest from the Playgrounds home.

Bookmark this page (Ctrl+D, or ⌘D on Mac) — it works offline the next time you need it.

Ninety playgrounds. Zero setup.

Every concept here is playable free, no account — and inside the program you learn to rebuild the machinery yourself.