Database Performance & SQL

How to explain EXPLAIN ANALYZE execution plans in PostgreSQL and MySQL.

Highlight PostgreSQL EXPLAIN (ANALYZE, BUFFERS) or MySQL EXPLAIN outputs and identify sequential table scans, bad row estimates, and missing indexes.

Best fit

Best for backend engineers, database administrators, and data analysts diagnosing slow SQL queries directly from logs or query explainers.

On-screen walkthrough

How this looks on a real webpage.

Instead of switching tabs and rebuilding context, highlight the exact passage that slowed you down and press your shortcut (default: Ctrl+Shift+X or Cmd+Shift+X on macOS, fully customizable in settings).

explain.dalibo.com/plan/example-seq-scan
Context: Detailed
1. Highlighted on page (PostgreSQL EXPLAIN (ANALYZE, BUFFERS) Query Plan Output)
Hash Join (cost=4215.10..18920.45 rows=1250 width=84) (actual time=48.210..312.450 rows=820 loops=1) Hash Cond: (o.user_id = u.id) Buffers: shared hit=1210 read=8420 -> Seq Scan on orders o (cost=0.00..12890.00 rows=482000 width=48) (actual time=0.035..184.210 rows=482000 loops=1) Filter: (status = 'pending'::text) Rows Removed by Filter: 472000 -> Hash (cost=3890.10..3890.10 rows=26000 width=36) (actual time=14.120..14.120 rows=26000 loops=1)
Ctrl+Shift+X“Where is the bottleneck in this query plan and what index will fix it?”
2. Vezz me on-screen answer overlay

1. **The Bottleneck**: The **`Seq Scan on orders o`** took 184ms and read **8,420 disk pages** because it scanned all **482,000 rows** sequentially—only to discard **472,000 rows** (`Rows Removed by Filter`)!

2. **Why it's slow**: Only 10,000 orders are `'pending'` (2% of the table), yet Postgres had to do a full table scan.

3. **The Fix**: Add a partial index on pending orders:

`CREATE INDEX idx_orders_pending ON orders (user_id) WHERE status = 'pending';`

This shrinks the index to just 10k rows and replaces the 184ms Seq Scan with an instantaneous Index Scan.

3. Suggested follow-up questions in thread
  • “Why did the query planner choose a Hash Join instead of a Nested Loop here?”
  • “What does `Buffers: shared hit=1210 read=8420` tell us about buffer cache hit ratio?”
Step-by-step workflow

How to run this workflow in place.

1

Highlight the EXPLAIN ANALYZE output in your browser

Select the tree output inside pgAdmin, DBeaver web viewers, Datadog Database Monitoring, or terminal logs.

2

Ask for the node with the highest actual time and disk reads

Press your shortcut and ask Vezz me which node consumed the most actual time and where estimated rows differed wildly from actual rows.

3

Request the exact composite or partial DDL index statement

Ask Vezz me for the specific `CREATE INDEX` syntax that targets the filter conditions and join keys.

Key details

Why this approach works better than switching tabs.

Decode nested execution plans in 10 seconds
Reading raw PostgreSQL or MySQL query plans requires parsing cost numbers, loop multipliers, and buffer cache hits.
  • Identifies costly Sequential Scans filtering out 90%+ of rows that should use an index
  • Spots row-estimation discrepancies (e.g., planner estimated 1 row but got 50,000) that trigger catastrophic Nested Loops
  • Suggests exact index definitions including partial indexes, covering indexes (`INCLUDE`), and expression indexes
Comparison Matrix

Diagnosing Slow Queries

Comparing in-page query plan breakdown with mental parsing and GUI visualizers.

ApproachStrengthsTradeoffs
Vezz me on EXPLAIN TextIsolates the single slowest node, explains row-filter waste, and outputs index DDL in 10sRequires pasting or highlighting the plan text
GUI Plan VisualizersDrawing colorful tree graphsStill requires you to know how to interpret buffer reads and cost formulas
Manual line-by-line readingDeep DB tuning masteryEasy to overlook loop multipliers (`loops=1000`) that multiply execution time 1,000x
Frequently asked questions

Common questions about database performance & sql.

Does Vezz me work on both PostgreSQL and MySQL query plans?

Yes! It accurately parses PostgreSQL `EXPLAIN (ANALYZE, BUFFERS)` trees as well as MySQL 8.0 `EXPLAIN ANALYZE` and traditional tabular format.

Can it diagnose lock contention and vacuum issues?

Yes. Highlight autovacuum logs, lock wait alerts, or buffer cache statistics and ask Vezz me for the operational root cause.

Which preset should I use for database queries?

Use our Regex & SQL Deconstructor preset or Senior Engineer Code Reviewer preset.

Related workflows & guides

Explore connected pages.

Available for Chrome and Firefox

Ready to try this workflow on your own reading?

Install Vezz me free, highlight text on any webpage, and press your customizable shortcut (default: Ctrl+Shift+X or Cmd+Shift+X on Mac) to get an answer right beside the source.