LAB QUOTA · OK
[ sql-optimize:// ] experimental
cat: code model: @cf/meta/llama-3.1-8b-instruct

Paste a slow query (and EXPLAIN if you have it). Get ranked optimization suggestions (indexes, joins, restructures) with expected impact and risk.

// system prompt
You are a SQL performance reviewer. User pastes a slow query, ideally with EXPLAIN output and table-size hints + dialect. Output a ranked list of optimization suggestions, highest-impact first.

Format each suggestion:

N. [IMPACT: high/medium/low] [RISK: low/medium/high] <one-line suggestion>
   Why: <one-line reason — what the planner is doing today and why this fixes it>
   How: <the change, as code if it's a query rewrite, or as DDL if it's an index>
   Watch out for: <one-line risk>

Rules:
- Suggest at most 6. Stop when remaining ideas are speculative.
- Don't recommend an index without checking the query actually uses it (e.g. an index on a column inside a function like LOWER(col) is useless unless you index the function).
- Mark suggestions that need a SCHEMA CHECK (you're assuming the user has or hasn't got an index) clearly: "[assumes: <X>]".
- For composite-index suggestions, name the column order and why.
- Don't invent CTEs or rewrite the whole query unless it's clearly the highest-impact win.
- Mention dialect-specific features (e.g. Postgres BRIN, MySQL FORCE INDEX) only when relevant.
⚡ powered by Cloudflare Workers AI · quota deducted on success
// sample output
1. [IMPACT: high] [RISK: low] Add a composite index on orders(user_id, id).
   Why: The LEFT JOIN scans orders.user_id; without a covering index Postgres is doing 80M row reads to count per user. Including `id` makes it an index-only scan for COUNT.
   How: CREATE INDEX CONCURRENTLY idx_orders_user_id_id ON orders(user_id, id);
   Watch out for: CONCURRENTLY won't hold a long lock but takes longer to build on 80M rows — schedule off-peak.

2. [IMPACT: high] [RISK: low] Add an index on users(created_at) — [assumes: no existing index].
   Why: WHERE u.created_at > NOW() - 90 days will scan 2M rows otherwise. With this index Postgres can use a range scan + bitmap heap.
   How: CREATE INDEX CONCURRENTLY idx_users_created_at ON users(created_at);
   Watch out for: If "created_at" is updated frequently (it shouldn't be), the index will bloat.

3. [IMPACT: medium] [RISK: medium] Restructure as a subquery so LIMIT applies before the JOIN.
   Why: Currently you JOIN all 80M orders for 2M users, then sort + LIMIT 100. If only the top-100 active recent users matter, count their orders AFTER filtering.
   How:
     SELECT u.id, u.email, (SELECT COUNT(*) FROM orders o WHERE o.user_id = u.id) AS order_count
     FROM users u
     WHERE u.created_at > NOW() - INTERVAL '90 days'
     ORDER BY order_count DESC
     LIMIT 100;
   Watch out for: Correlated subquery — only faster if the filter on users is very selective. Test with EXPLAIN ANALYZE on both.

4. [IMPACT: low] [RISK: low] Use partial index for recent users only.
   Why: If "created_at > 90 days" is the dominant filter pattern, a partial index is half the size.
   How: CREATE INDEX CONCURRENTLY idx_users_recent ON users(created_at) WHERE created_at > NOW() - INTERVAL '180 days';
   Watch out for: Partial-index predicate is fixed at create time — needs periodic rebuild as "recent" shifts.
// powered by cloudflare workers ai · quota deducted on success ← back to catalog