Iron Law
NEVER WRITE SQL WITHOUT KNOWING THE QUERY PLAN — USE EXPLAIN ANALYZE BEFORE CLAIMING A QUERY IS OPTIMIZED
When to Use This Skill
- Writing complex SQL queries or analytics (window functions, recursive CTEs, OLAP)
- Designing SQL for cloud-native platforms (BigQuery, Snowflake, Redshift, Aurora)
- Building HTAP or hybrid analytical/transactional systems
- Migrating from OLTP-only PostgreSQL to an analytics tier
- Dimensional modeling, data vault, star/snowflake schemas
- Integrating machine learning with SQL workloads
- Time-series analysis (TimescaleDB, InfluxDB, Apache Druid)
Do Not Use This Skill When
- You only need ORM-level guidance (use
python-dev, nestjs-api, or java-spring-api)
- The system is non-SQL or document-only (use
database-schema-designer for Firestore patterns)
- You need query optimization patterns for PostgreSQL OLTP (use
sql-optimization-patterns)
- You cannot access query plans or schema details
Quick Reference
| Workload |
Platform |
Key Consideration |
| OLTP (transactional) |
PostgreSQL |
Normalize to 3NF, index FKs and WHERE cols |
| OLAP (analytics) |
BigQuery / Snowflake / Redshift |
Denormalize, columnar storage, partition by date |
| HTAP (both) |
CockroachDB / TiDB |
Read replicas for analytics, avoid read-your-own-writes latency |
| Time-series |
TimescaleDB / InfluxDB |
Hypertables, continuous aggregates, retention policies |
| Data warehouse |
Redshift / Databricks |
Star schema, materialized views, query concurrency |
| Graph + SQL |
Neo4j / Amazon Neptune |
Cypher for traversal, SQL for aggregation |
Process
Phase 1 — Understand the Workload
- Classify: OLTP / OLAP / HTAP / time-series / data warehouse
- Identify read/write ratio, peak concurrency, data volume (rows, GB)
- Confirm platform and version (PostgreSQL 16, BigQuery, Snowflake Enterprise, etc.)
Phase 2 — Design the Query or Schema
- Apply appropriate normalization or denormalization for workload type
- For OLAP: star schema (fact + dimensions), SCD Type 2 for slowly changing dims
- For data vault: hubs, links, satellites pattern
- For event sourcing: append-only events table, aggregate projections
Phase 3 — Optimize and Validate
- Run
EXPLAIN ANALYZE (PostgreSQL) or query profile (BigQuery/Snowflake)
- Identify sequential scans, hash joins on large tables, spill to disk
- Apply indexes, partitioning, or materialization as evidence dictates
Phase 4 — Production Readiness
- Use read replicas for heavy analytics queries on OLTP primary
- Apply LIMIT + cursor pagination for large result sets
- Set statement_timeout for user-facing queries
- Enable connection pooling (PgBouncer) for high-concurrency workloads
Platform-Specific Capabilities
PostgreSQL (Primary Stack)
- Window functions:
OVER (PARTITION BY ... ORDER BY ...)
- Recursive CTEs: hierarchical data traversal
- JSON/JSONB:
@>, #>>, jsonb_path_query
- Full-text:
to_tsvector, ts_rank, GIN indexes
- Temporal:
timestamptz, AT TIME ZONE, generate_series for gaps
- Extensions:
pg_stat_statements, pg_trgm, uuid-ossp, pgcrypto
Cloud Analytics Platforms
- BigQuery: Standard SQL, partitioned tables, clustering,
INFORMATION_SCHEMA
- Snowflake: Zero-copy cloning, time-travel, micro-partitioning, tasks + streams
- Redshift: Distribution keys, sort keys, VACUUM + ANALYZE cadence
- Databricks: Delta Lake,
MERGE INTO, streaming + batch unification
Time-Series
- TimescaleDB: Hypertables, continuous aggregates, compression policies
- InfluxDB: Flux queries, bucket retention, downsampling tasks
- Apache Druid: Real-time ingestion, rollup, approximate aggregations (HLL, quantiles)
Advanced SQL Patterns
Window Functions
-- Running total + rank within partition
SELECT
user_id,
order_date,
total,
SUM(total) OVER (PARTITION BY user_id ORDER BY order_date) AS running_total,
RANK() OVER (PARTITION BY user_id ORDER BY total DESC) AS rank_in_user
FROM orders;
Recursive CTE (Hierarchical Data)
WITH RECURSIVE org_tree AS (
-- Base case: root nodes
SELECT id, name, parent_id, 0 AS depth
FROM employees WHERE parent_id IS NULL
UNION ALL
-- Recursive case
SELECT e.id, e.name, e.parent_id, ot.depth + 1
FROM employees e
JOIN org_tree ot ON e.parent_id = ot.id
)
SELECT * FROM org_tree ORDER BY depth, name;
HTAP Pattern — Separate Read/Write Paths
-- Write path: OLTP primary (PostgreSQL)
INSERT INTO orders (user_id, total, created_at) VALUES ($1, $2, NOW());
-- Read path: replica or analytics DB
-- Use logical replication to BigQuery/Snowflake for heavy aggregations
SELECT DATE_TRUNC('month', created_at), SUM(total)
FROM orders
GROUP BY 1 ORDER BY 1;
-- Route this to read replica, not primary
SCD Type 2 (Slowly Changing Dimensions)
-- Invalidate current record, insert new version
UPDATE dim_customers
SET valid_to = NOW(), is_current = FALSE
WHERE customer_id = $1 AND is_current = TRUE;
INSERT INTO dim_customers (customer_id, name, email, valid_from, valid_to, is_current)
VALUES ($1, $2, $3, NOW(), '9999-12-31', TRUE);
Anti-Patterns
- Running heavy OLAP aggregations on OLTP primary — use read replica or separate analytics DB
SELECT * on wide fact tables in analytics workloads — columns are stored separately in columnar DBs
- Non-partitioned tables for time-series data exceeding 1M rows — always partition by time
- Correlated subqueries in analytical queries — always transform to JOINs or window functions
- Implicit type casting in JOIN conditions — prevents index usage, causes full scans
- DDL inside transactions on BigQuery/Snowflake — not supported; manage schema changes separately
Documentation Sources
- PostgreSQL docs: Query MCP context7 with library ID
/postgresql/postgresql
- BigQuery: Query MCP context7 with library ID
/googleapis/google-cloud-bigquery
- Snowflake SQL reference:
WebFetch from Snowflake documentation
- TimescaleDB: Query MCP context7
Reference Files
(None yet — patterns are inline above. Add reference/cloud-platform-sql.md when cloud-specific patterns grow beyond this file.)
Related Skills
sql-optimization-patterns — PostgreSQL OLTP query tuning, EXPLAIN analysis, N+1 fixes, cursor pagination
database-schema-designer — Schema design, Flyway migrations, normalization, FK/index rules
vector-database — pgvector, HNSW/IVFFlat, RAG pipelines
python-dev — SQLAlchemy async, asyncpg, FastAPI integration
java-spring-api — R2DBC reactive PostgreSQL
nestjs-api — Prisma ORM, raw SQL via Prisma
1---2name: sql-pro3description: Masters modern SQL across PostgreSQL, BigQuery, Snowflake, and hybrid OLTP/OLAP systems — covering advanced query techniques, dimensional modeling, time-series SQL, and data warehouse patterns. Use when writing complex analytics SQL, designing cloud database schemas, or optimizing cross-platform SQL workloads.4---56## Iron Law7NEVER WRITE SQL WITHOUT KNOWING THE QUERY PLAN — USE EXPLAIN ANALYZE BEFORE CLAIMING A QUERY IS OPTIMIZED89## When to Use This Skill1011- Writing complex SQL queries or analytics (window functions, recursive CTEs, OLAP)12- Designing SQL for cloud-native platforms (BigQuery, Snowflake, Redshift, Aurora)13- Building HTAP or hybrid analytical/transactional systems14- Migrating from OLTP-only PostgreSQL to an analytics tier15- Dimensional modeling, data vault, star/snowflake schemas16- Integrating machine learning with SQL workloads17- Time-series analysis (TimescaleDB, InfluxDB, Apache Druid)1819## Do Not Use This Skill When2021- You only need ORM-level guidance (use `python-dev`, `nestjs-api`, or `java-spring-api`)22- The system is non-SQL or document-only (use `database-schema-designer` for Firestore patterns)23- You need query optimization patterns for PostgreSQL OLTP (use `sql-optimization-patterns`)24- You cannot access query plans or schema details2526## Quick Reference2728| Workload | Platform | Key Consideration |29|----------|----------|-------------------|30| OLTP (transactional) | PostgreSQL | Normalize to 3NF, index FKs and WHERE cols |31| OLAP (analytics) | BigQuery / Snowflake / Redshift | Denormalize, columnar storage, partition by date |32| HTAP (both) | CockroachDB / TiDB | Read replicas for analytics, avoid read-your-own-writes latency |33| Time-series | TimescaleDB / InfluxDB | Hypertables, continuous aggregates, retention policies |34| Data warehouse | Redshift / Databricks | Star schema, materialized views, query concurrency |35| Graph + SQL | Neo4j / Amazon Neptune | Cypher for traversal, SQL for aggregation |3637## Process3839### Phase 1 — Understand the Workload40- Classify: OLTP / OLAP / HTAP / time-series / data warehouse41- Identify read/write ratio, peak concurrency, data volume (rows, GB)42- Confirm platform and version (PostgreSQL 16, BigQuery, Snowflake Enterprise, etc.)4344### Phase 2 — Design the Query or Schema45- Apply appropriate normalization or denormalization for workload type46- For OLAP: star schema (fact + dimensions), SCD Type 2 for slowly changing dims47- For data vault: hubs, links, satellites pattern48- For event sourcing: append-only events table, aggregate projections4950### Phase 3 — Optimize and Validate51- Run `EXPLAIN ANALYZE` (PostgreSQL) or query profile (BigQuery/Snowflake)52- Identify sequential scans, hash joins on large tables, spill to disk53- Apply indexes, partitioning, or materialization as evidence dictates5455### Phase 4 — Production Readiness56- Use read replicas for heavy analytics queries on OLTP primary57- Apply LIMIT + cursor pagination for large result sets58- Set statement_timeout for user-facing queries59- Enable connection pooling (PgBouncer) for high-concurrency workloads6061## Platform-Specific Capabilities6263### PostgreSQL (Primary Stack)64- Window functions: `OVER (PARTITION BY ... ORDER BY ...)`65- Recursive CTEs: hierarchical data traversal66- JSON/JSONB: `@>`, `#>>`, `jsonb_path_query`67- Full-text: `to_tsvector`, `ts_rank`, GIN indexes68- Temporal: `timestamptz`, `AT TIME ZONE`, `generate_series` for gaps69- Extensions: `pg_stat_statements`, `pg_trgm`, `uuid-ossp`, `pgcrypto`7071### Cloud Analytics Platforms72- **BigQuery**: Standard SQL, partitioned tables, clustering, `INFORMATION_SCHEMA`73- **Snowflake**: Zero-copy cloning, time-travel, micro-partitioning, tasks + streams74- **Redshift**: Distribution keys, sort keys, VACUUM + ANALYZE cadence75- **Databricks**: Delta Lake, `MERGE INTO`, streaming + batch unification7677### Time-Series78- **TimescaleDB**: Hypertables, continuous aggregates, compression policies79- **InfluxDB**: Flux queries, bucket retention, downsampling tasks80- **Apache Druid**: Real-time ingestion, rollup, approximate aggregations (HLL, quantiles)8182## Advanced SQL Patterns8384### Window Functions85```sql86-- Running total + rank within partition87SELECT88 user_id,89 order_date,90 total,91 SUM(total) OVER (PARTITION BY user_id ORDER BY order_date) AS running_total,92 RANK() OVER (PARTITION BY user_id ORDER BY total DESC) AS rank_in_user93FROM orders;94```9596### Recursive CTE (Hierarchical Data)97```sql98WITH RECURSIVE org_tree AS (99 -- Base case: root nodes100 SELECT id, name, parent_id, 0 AS depth101 FROM employees WHERE parent_id IS NULL102 UNION ALL103 -- Recursive case104 SELECT e.id, e.name, e.parent_id, ot.depth + 1105 FROM employees e106 JOIN org_tree ot ON e.parent_id = ot.id107)108SELECT * FROM org_tree ORDER BY depth, name;109```110111### HTAP Pattern — Separate Read/Write Paths112```sql113-- Write path: OLTP primary (PostgreSQL)114INSERT INTO orders (user_id, total, created_at) VALUES ($1, $2, NOW());115116-- Read path: replica or analytics DB117-- Use logical replication to BigQuery/Snowflake for heavy aggregations118SELECT DATE_TRUNC('month', created_at), SUM(total)119FROM orders120GROUP BY 1 ORDER BY 1;121-- Route this to read replica, not primary122```123124### SCD Type 2 (Slowly Changing Dimensions)125```sql126-- Invalidate current record, insert new version127UPDATE dim_customers128SET valid_to = NOW(), is_current = FALSE129WHERE customer_id = $1 AND is_current = TRUE;130131INSERT INTO dim_customers (customer_id, name, email, valid_from, valid_to, is_current)132VALUES ($1, $2, $3, NOW(), '9999-12-31', TRUE);133```134135## Anti-Patterns136137- Running heavy OLAP aggregations on OLTP primary — use read replica or separate analytics DB138- `SELECT *` on wide fact tables in analytics workloads — columns are stored separately in columnar DBs139- Non-partitioned tables for time-series data exceeding 1M rows — always partition by time140- Correlated subqueries in analytical queries — always transform to JOINs or window functions141- Implicit type casting in JOIN conditions — prevents index usage, causes full scans142- DDL inside transactions on BigQuery/Snowflake — not supported; manage schema changes separately143144## Documentation Sources145146- PostgreSQL docs: Query MCP context7 with library ID `/postgresql/postgresql`147- BigQuery: Query MCP context7 with library ID `/googleapis/google-cloud-bigquery`148- Snowflake SQL reference: `WebFetch` from Snowflake documentation149- TimescaleDB: Query MCP context7150151## Reference Files152153*(None yet — patterns are inline above. Add `reference/cloud-platform-sql.md` when cloud-specific patterns grow beyond this file.)*154155## Related Skills156157- `sql-optimization-patterns` — PostgreSQL OLTP query tuning, EXPLAIN analysis, N+1 fixes, cursor pagination158- `database-schema-designer` — Schema design, Flyway migrations, normalization, FK/index rules159- `vector-database` — pgvector, HNSW/IVFFlat, RAG pipelines160- `python-dev` — SQLAlchemy async, asyncpg, FastAPI integration161- `java-spring-api` — R2DBC reactive PostgreSQL162- `nestjs-api` — Prisma ORM, raw SQL via Prisma