Formatting for the way queries are read
SQL is whitespace-insensitive, so formatting changes nothing about execution — but a long query written as one line is genuinely hard to reason about, and reasoning about queries is where correctness lives. The conventions that have settled are about making structure scannable: major keywords starting their own lines, joins each on a line with their conditions, and predicates in the WHERE clause stacked one per line.
Leading commas — placing the comma at the start of each line rather than the end — look strange initially and solve a practical problem: adding or removing a column changes one line rather than two, and a missing comma is visible as a misaligned column rather than hidden at the end of a line.
Indentation should reflect nesting. Subqueries and common table expressions indented one level make the query's shape legible at a glance, which matters most for exactly the queries that are hardest to read. Where a query has more than two levels of nesting, rewriting it as a chain of CTEs usually helps more than any amount of formatting.
Formatting does not make a query safe
A formatter rearranges whitespace. It does not validate the query, does not check that it does what you intend, and above all does not protect against SQL injection. That protection comes from one thing: never building queries by concatenating user input.
Parameterised queries — placeholders bound to values by the database driver — keep data and code separate, so a value containing a quote or a semicolon is treated as a string rather than as syntax. This is not a matter of escaping input carefully; escaping by hand fails in edge cases involving character encodings and multi-byte sequences, and it fails silently.
Stored procedures are not inherently safe either, since a procedure that builds dynamic SQL internally has the same flaw. The rule is about parameterisation at the point where values meet the query, wherever that is.
Reading a query for performance
Formatting makes structure visible, which is the first step in spotting performance problems. The patterns worth looking for are largely visual once a query is laid out: a function applied to a column in a WHERE clause, such as WHERE YEAR(created_at) = 2026, prevents the database using an index on that column — rewriting it as a range comparison usually restores it.
Leading wildcards in LIKE '%term' have the same effect, since a B-tree index cannot seek on an unknown prefix. SELECT * pulls columns nobody uses, which costs I/O and can prevent an index-only scan. Correlated subqueries in the select list execute once per row and are frequently rewritable as a join.
None of this replaces measurement. Every serious database offers EXPLAIN or an execution plan viewer, which reports what the optimiser actually chose rather than what you assume — and the answer is regularly surprising, particularly where statistics are stale or the data distribution is skewed.