SQL Audit Skill
When to Activate
Activate this skill when the user asks to:
- Review SQL queries for production readiness
- Audit database performance or index usage
- Analyze locking risks or concurrency issues
- Review MyBatis mapper XML files
- Check SQL scalability for large datasets
Hard Rule
- Audit ALL mapper XML files in the project — do not skip any.
- Every SQL statement must be checked against ALL review criteria below.
- Report findings with severity ratings — do not silently pass questionable queries.
Instructions
- Discover the project structure:
- Search for DDL schema files (e.g.,
*.sql in sqls/, db/, migration/, schema/, or src/main/resources/db/ directories) to understand all table definitions, indexes, partitions, and column types.
- Search for all MyBatis mapper XML files (typically
*Mapper.xml or *.xml in **/resources/mapper/ or **/resources/mybatis/ directories).
- If no DDL schema files are found, infer table structures from the mapper XML files and any entity/model Java classes.
- Read and analyze the DDL schema to understand table definitions, indexes, partitions, and column types.
- Read every MyBatis mapper XML found in the project.
- Audit each SQL statement against ALL of the criteria below.
- Produce a structured report grouped by mapper file, with severity ratings.
Review Criteria
1. Index Integrity
- Flag any
WHERE, JOIN, or ORDER BY clause referencing columns that lack a supporting index.
- Detect composite index misuse: queries that skip the leftmost prefix of a composite index (e.g., querying on
col_b alone when the index is (col_a, col_b)).
- Detect Implicit Type Conversion: parameter types that may differ from column types (e.g., passing a Java
Long to a VARCHAR column, or String to TINYINT), which silently invalidates index usage.
2. Execution Plan Risks
- Identify patterns leading to Full Table Scans:
- Leading wildcards:
LIKE '%abc'
- Functions applied to indexed columns:
WHERE YEAR(date_col) = 2024, WHERE DATE(created_at) = ...
OR conditions that prevent index usage
NOT IN / <> / != on indexed columns
- Flag
DATE_SUB(NOW(), INTERVAL ...) or similar date function comparisons on indexed columns — confirm the function is applied to the constant side, not the column side.
- Flag queries missing
LIMIT that could return unbounded result sets.
3. Concurrency & Locking
- Analyze Batch Polling queries (any SELECT used for polling pending/due/dispatched/timed-out rows) for:
- Missing
FOR UPDATE SKIP LOCKED or equivalent — concurrent pollers may claim the same rows.
- Non-indexed
WHERE conditions causing full-table lock scans.
ORDER BY on non-indexed columns under InnoDB row-level locking.
- Analyze Retention Cleanup / Batch Delete queries for:
- Large
LIMIT values that hold row locks for extended periods.
- Missing index on the filter columns (e.g.,
status + created_at combination).
- Potential deadlocks when concurrent deletes target overlapping row ranges.
- Flag any
UPDATE ... WHERE status = X without an index on status (or the relevant composite).
- Flag blanket status-reset UPDATEs (e.g.,
WHERE status = N without additional filters) for lock contention risk.
4. Resource Pressure
- Flag
SELECT * on tables with TEXT/MEDIUMTEXT/BLOB/LONGTEXT columns — these cause unnecessary I/O and memory pressure. Identify which columns are large-object types from the DDL schema.
- Flag N+1 query patterns: queries called per-item inside loops (check the Java mapper interfaces and service layer for loop-based calls).
- Flag Offset-based pagination on large datasets (
OFFSET N LIMIT M) — recommend keyset/cursor pagination instead.
- Flag batch INSERT without size limits that could generate oversized SQL statements.
5. Scalability (Production Blocker Detection)
- For each query, evaluate: "Will this work at 1M+ rows?"
- Flag queries that perform:
- Correlated subqueries or subquery in DELETE/UPDATE that may degrade to O(n²)
- Cartesian products from missing JOIN conditions
- COUNT(*) without a covering index
- Unbounded JOINs between large tables without LIMIT
- Flag
DELETE ... WHERE id IN (SELECT ...) anti-patterns — on MySQL this can cause issues with the same-table subquery limitation.
- Check partition pruning: if tables use partitioning, queries that don't filter by the partition key will scan all partitions.
Report Format
For each finding, report:
### [SEVERITY] Finding Title
**Mapper:** FileName.xml → `<queryId>`
**Line:** approximate line in XML
**Issue:** Clear description of the problem
**Risk:** What happens in production (latency, locks, OOM, etc.)
**Recommendation:** Specific fix with code example if applicable
Severity levels:
- CRITICAL — Will cause outages or data corruption at scale. Must fix before production.
- HIGH — Significant performance degradation or locking issues under load.
- MEDIUM — Suboptimal but tolerable at moderate scale. Should fix soon.
- LOW — Minor optimization opportunity or best-practice deviation.
Final Summary
End with:
- A severity count table (CRITICAL / HIGH / MEDIUM / LOW)
- Top 3 highest-priority fixes
- Suggested composite indexes to add (with exact DDL)
- Any schema-level recommendations (missing indexes, partition strategy improvements)
1---2name: audit-sql3description: Perform a production-readiness SQL audit on MyBatis mapper XML files. Use when reviewing SQL queries, auditing database performance, checking index usage, analyzing locking risks, or reviewing mapper XML files for a Java/MyBatis project.4---56# SQL Audit Skill78## When to Activate910Activate this skill when the user asks to:1112- Review SQL queries for production readiness13- Audit database performance or index usage14- Analyze locking risks or concurrency issues15- Review MyBatis mapper XML files16- Check SQL scalability for large datasets1718## Hard Rule1920- Audit ALL mapper XML files in the project — do not skip any.21- Every SQL statement must be checked against ALL review criteria below.22- Report findings with severity ratings — do not silently pass questionable queries.2324## Instructions25261. **Discover the project structure:**27 - Search for DDL schema files (e.g., `*.sql` in `sqls/`, `db/`, `migration/`, `schema/`, or `src/main/resources/db/` directories) to understand all table definitions, indexes, partitions, and column types.28 - Search for all MyBatis mapper XML files (typically `*Mapper.xml` or `*.xml` in `**/resources/mapper/` or `**/resources/mybatis/` directories).29 - If no DDL schema files are found, infer table structures from the mapper XML files and any entity/model Java classes.302. **Read and analyze** the DDL schema to understand table definitions, indexes, partitions, and column types.313. **Read every MyBatis mapper XML** found in the project.324. **Audit each SQL statement** against ALL of the criteria below.335. **Produce a structured report** grouped by mapper file, with severity ratings.3435## Review Criteria3637### 1. Index Integrity38- Flag any `WHERE`, `JOIN`, or `ORDER BY` clause referencing columns that lack a supporting index.39- Detect **composite index misuse**: queries that skip the leftmost prefix of a composite index (e.g., querying on `col_b` alone when the index is `(col_a, col_b)`).40- Detect **Implicit Type Conversion**: parameter types that may differ from column types (e.g., passing a Java `Long` to a `VARCHAR` column, or `String` to `TINYINT`), which silently invalidates index usage.4142### 2. Execution Plan Risks43- Identify patterns leading to **Full Table Scans**:44 - Leading wildcards: `LIKE '%abc'`45 - Functions applied to indexed columns: `WHERE YEAR(date_col) = 2024`, `WHERE DATE(created_at) = ...`46 - `OR` conditions that prevent index usage47 - `NOT IN` / `<>` / `!=` on indexed columns48- Flag `DATE_SUB(NOW(), INTERVAL ...)` or similar date function comparisons on indexed columns — confirm the function is applied to the constant side, not the column side.49- Flag queries missing `LIMIT` that could return unbounded result sets.5051### 3. Concurrency & Locking52- Analyze **Batch Polling** queries (any SELECT used for polling pending/due/dispatched/timed-out rows) for:53 - Missing `FOR UPDATE SKIP LOCKED` or equivalent — concurrent pollers may claim the same rows.54 - Non-indexed `WHERE` conditions causing full-table lock scans.55 - `ORDER BY` on non-indexed columns under InnoDB row-level locking.56- Analyze **Retention Cleanup / Batch Delete** queries for:57 - Large `LIMIT` values that hold row locks for extended periods.58 - Missing index on the filter columns (e.g., `status` + `created_at` combination).59 - Potential deadlocks when concurrent deletes target overlapping row ranges.60- Flag any `UPDATE ... WHERE status = X` without an index on `status` (or the relevant composite).61- Flag blanket status-reset UPDATEs (e.g., `WHERE status = N` without additional filters) for lock contention risk.6263### 4. Resource Pressure64- Flag **`SELECT *`** on tables with `TEXT`/`MEDIUMTEXT`/`BLOB`/`LONGTEXT` columns — these cause unnecessary I/O and memory pressure. Identify which columns are large-object types from the DDL schema.65- Flag **N+1 query patterns**: queries called per-item inside loops (check the Java mapper interfaces and service layer for loop-based calls).66- Flag **Offset-based pagination** on large datasets (`OFFSET N LIMIT M`) — recommend keyset/cursor pagination instead.67- Flag batch INSERT without size limits that could generate oversized SQL statements.6869### 5. Scalability (Production Blocker Detection)70- For each query, evaluate: "Will this work at 1M+ rows?"71- Flag queries that perform:72 - **Correlated subqueries** or **subquery in DELETE/UPDATE** that may degrade to O(n²)73 - **Cartesian products** from missing JOIN conditions74 - **COUNT(*)** without a covering index75 - **Unbounded JOINs** between large tables without LIMIT76- Flag `DELETE ... WHERE id IN (SELECT ...)` anti-patterns — on MySQL this can cause issues with the same-table subquery limitation.77- Check **partition pruning**: if tables use partitioning, queries that don't filter by the partition key will scan all partitions.7879## Report Format8081For each finding, report:8283```84### [SEVERITY] Finding Title85**Mapper:** FileName.xml → `<queryId>`86**Line:** approximate line in XML87**Issue:** Clear description of the problem88**Risk:** What happens in production (latency, locks, OOM, etc.)89**Recommendation:** Specific fix with code example if applicable90```9192Severity levels:93- **CRITICAL** — Will cause outages or data corruption at scale. Must fix before production.94- **HIGH** — Significant performance degradation or locking issues under load.95- **MEDIUM** — Suboptimal but tolerable at moderate scale. Should fix soon.96- **LOW** — Minor optimization opportunity or best-practice deviation.9798## Final Summary99100End with:1011. A severity count table (CRITICAL / HIGH / MEDIUM / LOW)1022. Top 3 highest-priority fixes1033. Suggested composite indexes to add (with exact DDL)1044. Any schema-level recommendations (missing indexes, partition strategy improvements)