QueryAudit¶
Stop shipping slow queries. Catch N+1, missing indexes, and 57 other SQL anti-patterns automatically during your JUnit tests.
57 Detection Rules¶
Catches N+1 queries, missing indexes, SELECT *, DML anti-patterns, batch insert optimization, functions in WHERE clauses, implicit type conversions, locking risks, ORM inefficiencies, and more.
100% Reliable¶
Confirmed detections are structural -- they inspect SQL text and index metadata, not runtime data. No flaky heuristics. No false positives. If QueryAudit flags it, it is a real problem.
Zero Config¶
Add one annotation to your test class. That's it. QueryAudit auto-discovers your DataSource, intercepts queries, analyzes them, and reports issues. Works with JUnit 5 and Spring Boot. Supports MySQL and PostgreSQL.
Actionable Reports¶
Every issue includes the exact SQL statement, affected table, column, the detection rule that fired, and a concrete fix suggestion you can apply immediately.
How It Works¶
QueryAudit hooks into your test's DataSource via a lightweight proxy. During test execution, it captures every SQL statement. After the test completes, it:
- Parses each query to identify tables, columns, joins, and clauses
- Fetches index metadata from your database (MySQL
SHOW INDEXor PostgreSQLpg_catalog) - Cross-references the query structure against actual indexes
- Applies 57 detection rules covering N+1, missing indexes, DML safety, locking risks, and more
- Produces a structured report with severity, root cause, and fix suggestions
No runtime agents. No production overhead. Just add an annotation.
See It in Action¶
Add a single annotation to any test class:
@SpringBootTest
@QueryAudit // (1)!
class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
void findOrdersWithItems() {
List<Order> orders = orderService.findAllWithItems();
assertThat(orders).hasSize(5);
}
}
- That's it. No configuration, no extra beans, no proxy wiring.
Run your tests, and QueryAudit produces a report like this:
================================================================================
QUERY AUDIT REPORT
OrderServiceTest (8 queries analyzed)
================================================================================
CONFIRMED ISSUES (action required)
────────────────────────────────────────────────────────────────────────────────
[ERROR] N+1 Query Detected
Repeated query: select * from order_items where order_id = ?
Executions: 5 times (threshold: 3)
Suggestion: Use JOIN FETCH or @EntityGraph to load order_items
with the parent query.
[ERROR] Missing Index
Query: select * from order_items where order_id = ?
Table: order_items
Column: order_id
Suggestion: CREATE INDEX idx_order_items_order_id
ON order_items (order_id);
[WARNING] Repeated single-row INSERT should use batch insert
Query: insert into orders (...) values (?, ?, ?)
Table: orders
Detail: Single-row INSERT executed 10 times. Each INSERT causes a
separate network round-trip and log flush.
Suggestion: Use batch INSERT (saveAll() in JPA with hibernate.jdbc.batch_size).
────────────────────────────────────────────────────────────────────────────────
INFO (for review)
────────────────────────────────────────────────────────────────────────────────
[WARNING] SELECT * Usage
Query: select * from orders where user_id = ?
Table: orders
Suggestion: List only the columns you need
================================================================================
3 confirmed issues | 1 info | 8 queries
================================================================================
CONFIRMED vs INFO
CONFIRMED issues are structural problems -- missing indexes, N+1 patterns, unsafe DML. These will cause performance issues at scale and should be fixed.
INFO items are best-practice suggestions like avoiding SELECT *. They won't fail your build by default, but are worth reviewing.
Why QueryAudit?¶
Most teams discover query performance problems in one of two painful ways: a production incident, or a slow code review where someone manually checks SQL logs.
Existing tools help with observability -- they let you see your queries:
| Tool | What it does | What it doesn't do |
|---|---|---|
| datasource-proxy | Logs queries and execution time | No analysis, no detection |
| p6spy | Logs queries with bind parameters | Same -- logging only |
| Spring Hibernate statistics | Counts queries per session | Counts, but doesn't analyze |
QueryAudit closes the gap. It doesn't just log queries -- it applies 57 detection rules to every captured query, cross-references index metadata from your database (MySQL SHOW INDEX or PostgreSQL pg_catalog), and produces a structured report with concrete fix suggestions.
| Capability | datasource-proxy | p6spy | QueryAudit |
|---|---|---|---|
| Query logging | |||
| Bind parameter capture | |||
| N+1 detection | |||
| Missing index detection | |||
| DML anti-pattern detection | |||
| SQL anti-pattern detection | |||
| Query count regression | |||
| Fix suggestions | |||
| CI/CD fail-on-issue |
Getting Started¶
Ready to add QueryAudit to your project? It takes about two minutes.