Skip to content
Back to skills

Write Sql Query

ASecurity

Use when writing, reviewing, or optimizing SQL queries for correctness, performance, and maintainability

  • 4 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 8, 2026
ai-agentsgosqlgitdatabaseperformancedocumentation

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add jeffreytse/grimoire-core --skill write-sql-query --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Write Sql Query?

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

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

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: write-sql-query
description: Use when writing, reviewing, or optimizing SQL queries for correctness, performance, and maintainability
source: Joe Celko "SQL for Smarties" (5th ed., Morgan Kaufmann 2014); Use The Index, Luke (use-the-index-luke.com); PostgreSQL documentation
tags: [sql, database, performance, query-optimization, indexing, data]
verified: true
---

# Write SQL Query

Write SQL queries that are correct, index-aware, readable, and safe against injection and unintended side effects.

## Why This Is Best Practice

**Adopted by:** PostgreSQL community (Use The Index, Luke), Google (BigQuery SQL style guide), GitLab (SQL query guidelines in engineering handbook)
**Impact:** A missing index on a WHERE clause column can cause full table scans — a 10ms query becomes 10 seconds on a 10M row table. Celko's patterns and index-aware SQL are the standard in performance-critical data engineering.

**Why best:** Most SQL performance problems have the same root cause: the query does not use an available index, or no appropriate index exists. Writing index-aware SQL from the start costs nothing; retroactively optimizing a slow query in production is expensive and disruptive.

## Steps

1. **Understand the execution plan first** — For any non-trivial query: `EXPLAIN ANALYZE` (Postgres), `EXPLAIN FORMAT=JSON` (MySQL), or `EXPLAIN PLAN` (Oracle) before assuming it is efficient.
2. **Write SARGable predicates** — Ensure WHERE clause conditions can use an index: avoid wrapping indexed columns in functions (`WHERE YEAR(created_at) = 2026` → not SARGable; `WHERE created_at >= '2026-01-01'` → SARGable).
3. **Select only needed columns** — Never `SELECT *` in production queries; enumerate columns. Reduces I/O, prevents index-only scan breakage, and avoids surprises when schema changes.
4. **Use JOINs explicitly** — Always specify JOIN type (INNER, LEFT, etc.); never use implicit comma-joins in FROM clause. Explicit JOINs are readable and unambiguous.
5. **Avoid N+1 patterns** — Never execute queries inside loops; use JOIN or a subquery to batch the operation. N+1 is the #1 application-layer SQL anti-pattern.
6. **Use CTEs for readability** — Break complex queries into named CTEs (`WITH ... AS (...)`) for readability; modern optimizers inline CTEs efficiently (Postgres 12+, BigQuery).
7. **Parameterize all user inputs** — Never concatenate user input into SQL strings. Always use prepared statements or parameterized queries; SQL injection is trivially exploitable.

## Rules

- Never run an UPDATE or DELETE without a WHERE clause — add a `LIMIT 1` guard in development to prevent accidents.
- Always test queries on a representative dataset size — a query that runs in 50ms on 1,000 rows may take 50 seconds on 1,000,000.
- Wrap multi-statement data mutations in a transaction; rollback on error.
- Avoid `SELECT DISTINCT` as a band-aid — it usually signals a missing JOIN condition or a data model problem.

## Examples

Non-SARGable (bad):
```sql
SELECT * FROM orders WHERE DATE(created_at) = '2026-03-01';
-- Function on column prevents index use
```

SARGable (good):
```sql
SELECT order_id, total, status
FROM orders
WHERE created_at >= '2026-03-01' AND created_at < '2026-03-02';
-- Range scan on index; only needed columns selected
```

## Common Mistakes

- **`SELECT *` in production** — fetches unused columns, breaks index-only scans, causes hidden bugs when columns are added/dropped.
- **Implicit type coercion in WHERE** — `WHERE user_id = '42'` when `user_id` is integer triggers type cast on every row, preventing index use.
- **Correlated subqueries in SELECT** — executes the subquery once per row; replace with a JOIN or window function.

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…