--- name: sql-optimization-patterns type: reference description: "Provides SQL optimization patterns for query performance, indexing strategies, schema design, and database tuning. Use when optimizing slow queries, designing indexes, or tuning database performance." paths: ["**/*.sql", "**/migrations/**"] effort: 3 allowed-tools: Read, Glob, Grep, Bash user-invocable: true when_to_use: "When optimizing slow SQL queries, designing indexes, or tuning database performance" --- # SQL Optimization Patterns Query optimization, indexing, and performance tuning for PostgreSQL, MySQL, and SQLite. ## Index Strategy ### When to Create Index \`\`\`sql -- High selectivity columns (many unique values) CREATE INDEX idx_orders_user_id ON orders(user_id); -- Composite index: order matters (equality first, then range) CREATE INDEX idx_orders_user_date ON orders(user_id, created_at DESC); -- Covering index (includes all needed columns) CREATE INDEX idx_orders_covering ON orders(user_id, status) INCLUDE (total, created_at); \`\`\` ### When NOT to Index - Low cardinality columns (boolean, status with few values) - Small tables (< 1000 rows) - Write-heavy tables with rare reads ## Query Patterns ### Avoid SELECT * \`\`\`sql -- Bad SELECT * FROM orders WHERE user_id = 1; -- Good (select only needed columns) SELECT id, total, status FROM orders WHERE user_id = 1; \`\`\` ### Avoid N+1 (use JOIN or subquery) \`\`\`sql -- Bad: N+1 queries from application -- Good: Single query with JOIN SELECT o.id, o.total, u.name FROM orders o JOIN users u ON o.user_id = u.id WHERE o.status = 'pending'; \`\`\` ### Pagination (keyset, not OFFSET) \`\`\`sql -- Bad: OFFSET scans all skipped rows SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 10000; -- Good: Keyset pagination SELECT * FROM orders WHERE id > 10000 ORDER BY id LIMIT 20; \`\`\` ## EXPLAIN ANALYZE \`\`\`sql EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 1 AND status = 'pending'; \`\`\` Read output: - Seq Scan = missing index - Index Scan = good - Nested Loop with high row count = check join strategy ## Schema Anti-Patterns | Anti-Pattern | Problem | Fix | |-------------|---------|-----| | EAV (Entity-Attribute-Value) | No type safety, slow queries | Use JSONB or proper columns | | God table | Too many columns | Normalize into related tables | | No constraints | Data integrity issues | Add CHECK, FK, UNIQUE constraints | | String dates | Sorting/filtering issues | Use TIMESTAMP type | ## Connection Pooling \`\`\` App → Pool (min: 5, max: 20) → PostgreSQL \`\`\` Tools: PgBouncer (PostgreSQL), ProxySQL (MySQL). ## Related Skills - `database-architect` — schema design - `postgres-patterns` — PostgreSQL specifics - `nosql-expert` — NoSQL alternatives - `db-review` — database code review