Two SQL Reviews Every Query Should Pass
July 31, 2026 · DevTools
Every SQL query deserves two reviews before it ships: one for security (does it let an attacker in?) and one for performance (does it scale past a few rows?). Neither needs a running database — the dangerous patterns are well known and easy to spot in the text. Here is what to look for in each.
Review 1: Is it injectable?
SQL injection happens when untrusted input is concatenated into a query and the database interprets it as code. The payloads are remarkably consistent, which makes them easy to scan for:
- Tautologies —
OR '1'='1',OR 1=1— make aWHEREclause always true, bypassing logins and filters. UNION SELECT— appends a second result set to exfiltrate data from other tables.- Stacked queries — a
;followed by a new statement (; DROP TABLE users). - Comments —
--and/* */to truncate or break up the original query. - Time-based blind —
SLEEP(),WAITFOR DELAY,pg_sleep()to infer data through response timing. - Schema enumeration —
information_schema,sysobjectsto map the database.
Paste a suspect payload, a form value, or a query fragment into the SQL Injection Detector and it runs these signatures, reports each match with an explanation, classifies the injection type, and scores the payload 0–100. A classic login bypass scores critical:
admin' OR '1'='1' --
The important caveat: a clean scan is not proof of safety. Heuristics catch the obvious, not every obfuscated variant. The real fix is always parameterized queries (prepared statements) — bind variables can't become code no matter what the input contains. Use the detector to prioritize and to demonstrate the risk, then fix the construction.
Review 2: Is it fast?
Performance problems also cluster into a small set of anti-patterns, and you can find most of them by reading the query:
SELECT *— fetches every column, more I/O than needed and brittle when the schema changes.- Leading-wildcard
LIKE—LIKE '%term'can't use a normal index and forces a full scan. - No
WHERE— a read or modify with no predicate scans every row. - Comma cross joins —
FROM users, orderswith no join condition produces a Cartesian product. NOT IN— breaks entirely if the subquery returns aNULL;NOT EXISTSis safer and often faster.- Functions on columns —
WHERE LOWER(name) = ?disables the index onname. ORDER BYwithoutLIMIT— sorts an unbounded set.
The SQL Performance Analyzer flags each of these, ranks them by severity with a concrete suggestion, and scores the query 0–100. A query like:
SELECT * FROM users WHERE name LIKE '%ada%'
loses points twice — for SELECT * and for the leading-wildcard LIKE. The analyzer tells you exactly which penalties apply and why.
This review is schema-agnostic, so it points at likely problems fast. The final verdict still depends on indexes, row counts, and the real execution plan — confirm each change with EXPLAIN on production-sized data.
Two reviews, one habit
Run the injection check on anything that touches user input, and run the performance check on anything that might touch a large table. Both run in your browser, neither needs a database, and together they catch the two failure modes that embarrass teams in production. And if you've moved to documents, the NoSQL Validator does the same shape-check for MongoDB $jsonSchema.