Skip to content
Back to skills

Sql Query Optimization

ASecurity

Use when optimizing SQL query performance.

  • 2 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 10, 2026
ai-agentsgosqldatabaseperformance

Works with

  • cursor

Security analysis

A100/100

Scanned September 10, 2026

npx -y skills add LoopyLuci/Skills --skill sql-query-optimization --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sql Query Optimization?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sql Query Optimization
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loopyluci-sql-query-optimization/badge)](https://www.skillsdirectory.com/skills/loopyluci-sql-query-optimization)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sql-query-optimization
description: "Use when optimizing SQL query performance."
category: software-development
tags: [sql, optimization, database, queries, performance]
---
# SQL Query Optimization

Optimizing SQL queries for performance.

## Query Analysis

```sql
-- EXPLAIN ANALYZE (PostgreSQL)
EXPLAIN (ANALYZE, BUFFERS, TIMING) 
SELECT * FROM orders WHERE status = 'pending';

-- Look for:
-- Seq Scan on large tables → needs index
-- Nested Loop on large datasets → needs join optimization
-- Sort on unindexed column → needs index
-- High buffer usage → memory/cache issue
```

## Index Strategies

```sql
-- B-tree (default, for equality + range)
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_created ON orders(created_at DESC);

-- Composite (column order matters)
-- Put equality columns first, range columns last
CREATE INDEX idx_orders_status_date ON orders(status, created_at);
-- WHERE status = 'pending' AND created_at > '2024-01-01' → USES INDEX

-- Partial (only index relevant rows)
CREATE INDEX idx_orders_active ON orders(created_at) 
    WHERE status != 'cancelled';

-- Covering (include extra columns to avoid table access)
CREATE INDEX idx_orders_covering ON orders(status) 
    INCLUDE (total_amount, customer_id);
```

## Join Optimization

```sql
-- Prefer hash joins for large, unsorted datasets
-- Prefer merge joins for pre-sorted data
-- Prefer nested loops for small right side

-- Set join order explicitly (PostgreSQL)
SET join_collapse_limit = 1;
SET from_collapse_limit = 1;
-- Then order tables in FROM clause from most selective to least

-- Use EXISTS instead of DISTINCT for existence
-- SLOW
SELECT DISTINCT c.* FROM customers c JOIN orders o ON c.id = o.customer_id;
-- FAST
SELECT * FROM customers c WHERE EXISTS (SELECT 1 FROM orders o WHERE o.customer_id = c.id);
```

## Pagination Performance

```sql
-- OFFSET is slow for deep pages (reads all skipped rows)
-- SLOW
SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 100000;

-- Keyset/cursor pagination (fast, consistent)
-- FIRST PAGE
SELECT * FROM orders ORDER BY id LIMIT 20;
-- NEXT PAGE (use last id from previous page)
SELECT * FROM orders WHERE id > :last_id ORDER BY id LIMIT 20;
```

## Common Anti-Patterns

```sql
-- 1. SELECT * (fetches unnecessary columns)
SELECT id, name, email FROM users;  -- instead of SELECT *

-- 2. Functions on indexed columns (breaks index usage)
WHERE DATE(created_at) = '2024-01-01'
-- FIX: WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02'

-- 3. Implicit type conversion
WHERE phone = 1234567890  -- varchar = integer → no index use
-- FIX: WHERE phone = '1234567890'

-- 4. N+1 in ORM (not SQL but common pattern)
# Bad: for user in users: query = SELECT * FROM orders WHERE user_id = user.id
# Good: Order.objects.filter(user_id__in=[u.id for u in users])
```

## Pitfalls

- Indexes speed up reads but slow writes — don't over-index
- Composite index column order matters: equality → range → group by
- EXPLAIN ANALYZE actually runs the query — use on SELECT only in production
- Vacuum/ANALYZE maintain statistics — stale stats = bad query plans
- Connection pooling prevents connection overhead but doesn't fix slow queries

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…