← IndexEntry № 183·coding

Diagnose and rewrite a slow SQL query using its plan

Reads a query plan to explain why a SQL statement is slow, then rewrites it and recommends indexes.

Optimized for
ChatGPTClaude
§ When to use this

When a query is slow, guessing wastes time—the query plan already holds the answer if you can read it. This prompt acts as a performance partner: you paste the slow query, its EXPLAIN (or EXPLAIN ANALYZE) output, and the relevant table sizes and indexes, and it diagnoses the actual cause—sequential scans, a missing index, a bad join order, non-sargable predicates that defeat indexes, or row-estimate errors that mislead the planner. Then it rewrites the query to return identical results faster and recommends indexes, honestly including the write-time and storage cost of adding them. The key inputs are the real plan and accurate schema info; without the plan, any advice is speculation. Name the database engine, because plan formats and tuning options differ across Postgres, MySQL, and others. Use the 'what to re-measure' section to confirm the fix actually helped on production-like data rather than assuming it did—plans change with data volume and statistics.

§ The Prompt— fill in the fields, then copy or open in a tool
§ Customize0/4 fields filled
your prompt — fill the fields above
You are an expert in SQL performance tuning on [DATABASE_ENGINE]. I will give you a slow query, its EXPLAIN/EXPLAIN ANALYZE output, and the relevant table sizes and indexes. Diagnose why it is slow—full scans, missing indexes, bad join order, non-sargable predicates, or row-estimate errors. Then rewrite the query to be faster while returning identical results, and recommend any indexes worth adding (with the trade-offs of adding them). Table info and indexes: [SCHEMA_INFO]. Query:

[SQL_QUERY]

Explain plan:

[EXPLAIN_OUTPUT]

Return the diagnosis, the rewritten query, suggested indexes, and what to re-measure.
Open with your prompt →ChatGPTClaudeSends your filled-in prompt straight into a new chat.
§ Example Output

What you can expect back

Diagnosis: The planner does a full Seq Scan over ~50M rows because `DATE(created_at)` wraps the column in a function—this is a non-sargable predicate, so no index on `created_at` can be used even if one existed.

Rewrite (same results, sargable):
```sql
SELECT * FROM orders
WHERE created_at >= '2026-06-01'
  AND created_at <  '2026-06-02';
```
This is a range over the raw column, which an index can serve.

Suggested index:
```sql
CREATE INDEX idx_orders_created_at ON orders(created_at);
```
Trade-off: speeds this and similar date-range queries, but adds write overhead on a high-insert table and ~1–2 GB of storage at 50M rows. If you usually filter by user too, consider (user_id, created_at) instead.

Re-measure: run EXPLAIN ANALYZE after indexing; confirm an Index/Bitmap scan replaces the Seq Scan and check actual vs. estimated rows.

Illustrative example — your results will vary by tool and inputs.

§ Pro Tips

Get sharper results

  • 01Provide EXPLAIN ANALYZE, not just EXPLAIN—actual vs. estimated rows reveals planner misestimates.
  • 02Include real row counts; advice differs wildly between a 10k-row and a 50M-row table.
  • 03Watch for SELECT * — fetching unused columns can defeat covering-index opportunities.
  • 04Re-measure on production-like data; a fix that wins on a small table can lose at scale.
§ Variations

Adapt it for your case

No plan available

Add 'I can't get an EXPLAIN yet—infer likely bottlenecks from the query and schema, and tell me what to capture.'

Covering index focus

Add 'Prefer a covering/INCLUDE index so the query can be satisfied from the index alone, and show the DDL.'

Tags#sql#performance#query-optimization
§ FAQ

Common questions

Do I really need the EXPLAIN output?

It's the single most useful input. Without it the model guesses; with it, it can name the exact scan or join causing the slowdown.

Will the rewrite return the same rows?

The prompt requires identical results, but verify—especially around date boundaries and NULL handling—by comparing row counts before and after.

Why does it warn about adding an index?

Indexes speed reads but slow writes and use storage. On high-insert tables that trade-off is real, so the prompt surfaces it deliberately.

§ Related Entries

You may also need