sql-idioms
SkillDatabases & dataSQL rewards set-based thinking, explicit joins, and query plan awareness. Idiomatic SQL = readable, performant, migration-safe.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the sql-idioms skill
About this capability
Comprehensive sets of standards and practices designed to elevate the capabilities of AI coding agents.
What this skill tells your AI
The instructions your AI receives, as published by irahardianto/awesome-agv in .agents/skills/sql-idioms/SKILL.md and read by ahel’s review.
SQL Idioms and Patterns
SQL rewards set-based thinking, explicit joins, and query plan awareness. Idiomatic SQL = readable, performant, migration-safe.
Scope: SQL coding idioms. For database design principles, load
@.agents/rules/database-design-principles.md.
Query Patterns
-
CTEs over subqueries for readability:
-- ✅ CTE — readable, debuggable WITH active_tasks AS ( SELECT id, title, priority, user_id FROM tasks WHERE status = 'active' ) SELECT u.name, COUNT(at.id) AS task_count FROM users u JOIN active_tasks at ON u.id = at.user_id GROUP BY u.name; -- ❌ Nested subquery — hard to read SELECT u.name, (SELECT COUNT(*) FROM tasks t WHERE t.user_id = u.id AND t.status = 'active') FROM users u; -
Window functions for ranking, running totals:
SELECT title, priority, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) AS rn FROM tasks; -
Explicit
JOINsyntax — never implicit joins inWHERE. -
Parameterized queries — never string concatenation. (See .agents/rules/security-mandate.md.)
Migration Safety
For migration strategy (additive-first, two-phase drops, reversibility), see @.agents/rules/database-design-principles.md § Migrations.
- Index creation:
CONCURRENTLYon PostgreSQL for zero-downtime. - Idempotent DDL — use
IF NOT EXISTSfor tables/indexes;DO $$ ... pg_constraint check ... $$for constraints.
Index Strategy
-
Choose the right index type:
- B-tree (default):
=,<,>,BETWEEN,IN,IS NULL - GIN: arrays, JSONB (
@>), full-text search (@@) - GiST: geometric data, range types, nearest-neighbor (KNN)
- BRIN: large time-series tables (10-100x smaller than B-tree)
- Hash: equality-only (marginally faster than B-tree for
=)
- B-tree (default):
-
Composite indexes — column order matters:
-- Equality columns first, range columns last (leftmost prefix rule) CREATE INDEX idx ON orders (status, created_at); -- Works for: WHERE status = 'pending' -- Works for: WHERE status = 'pending' AND created_at > '2024-01-01' -- Does NOT work for: WHERE created_at > '2024-01-01' (alone) -
Partial indexes for filtered queries:
-- Index only active rows (5-20x smaller) CREATE INDEX idx_users_active_email ON users (email) WHERE deleted_at IS NULL; -
Covering indexes to avoid heap fetches:
-- INCLUDE non-searchable columns for index-only scans CREATE INDEX idx_orders_status ON orders (status) INCLUDE (customer_id, total); -
Indexes on foreign keys — always. PostgreSQL does not auto-index FKs.
Performance
-
EXPLAIN (ANALYZE, BUFFERS)before optimizing — never guess.- Seq Scan on large table = missing index
- Rows Removed by Filter = poor selectivity
read >> hitin Buffers = data not cached- Sort Method: external merge =
work_memtoo low
-
Avoid
SELECT *— list specific columns. -
Keyset pagination over OFFSET for large datasets:
-- O(1) regardless of page depth SELECT * FROM products WHERE (created_at, id) > ($1, $2) ORDER BY created_at, id LIMIT 20;Use
LIMIT/OFFSETonly for small, bounded result sets.
Concurrency & Locking
-
Prevent deadlocks — consistent lock ordering:
-- Acquire locks in PK order before updating SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE; -
SKIP LOCKED for queue processing:
-- Workers skip locked rows instead of blocking (10x throughput) UPDATE jobs SET status = 'processing' WHERE id = ( SELECT id FROM jobs WHERE status = 'pending' ORDER BY created_at LIMIT 1 FOR UPDATE SKIP LOCKED ) RETURNING *; -
Advisory locks for application-level coordination:
SELECT pg_advisory_xact_lock(hashtext('daily_report')); -- Released on COMMIT -
statement_timeout— always set per-session to prevent runaway queries.
Data Operations
-
UPSERT — atomic insert-or-update (no race conditions):
INSERT INTO settings (user_id, key, value) VALUES ($1, $2, $3) ON CONFLICT (user_id, key) DO UPDATE SET value = EXCLUDED.value, updated_at = now(); -
Bulk loading — use
COPYover batch INSERTs for large imports. -
Batch inserts — multiple rows per statement, not one INSERT per row.
Diagnostics
-
pg_stat_statements— enable to identify top resource-consuming queries by total time and call frequency. -
VACUUM/ANALYZE — run
ANALYZEafter large data changes. Tuneautovacuum_vacuum_scale_factorfor high-churn tables.
Advanced PostgreSQL
- Full-text search: use
tsvector+ GIN index, notLIKE '%term%'. - JSONB indexing: GIN (
jsonb_path_opsfor@>only — 2-3x smaller), expression indexes for key lookups.
Naming
Follow conventions in @.agents/rules/database-design-principles.md § Schema (Naming).
Anti-Patterns
- ❌ Missing indexes on foreign keys
- ❌ N+1 queries (use
JOINor batch) - ❌ String concatenation in queries (SQL injection risk)
- ❌ Storing comma-separated values in a single column
- ❌
OFFSETpagination on large datasets (use keyset) - ❌
timestampwithout timezone (usetimestamptz) - ❌
varchar(n)without reason (usetext) - ❌ Random UUID v4 as primary key on large tables (index fragmentation)
- ❌ Check-then-insert pattern (race condition — use UPSERT)
Related
- Database Design Principles @.agents/rules/database-design-principles.md
- Security Principles .agents/rules/security-principles.md
- Performance Optimization Principles @.agents/rules/performance-optimization-principles.md
Signals
- GitHub stars
- 156
- Forks
- 53
- Last commit
- Aug 2026
Advanced
- Catalog kind
- skill
- Gateway key
sql-idioms- Source
- github.com/irahardianto/awesome-agv