Sargable Predicates

Sargable Predicates and Query Rewriting

A predicate is sargable when the bare column meets a value computed once, so an index can seek. A function, arithmetic or type conversion on the column forces per-row evaluation: move the work to the constant side (price > 100 / 1.1, a date range, not YEAR(ordered_at) = 2026) or index the expression (Generated Columns). The slow query log proves a rewrite; it needs SET GLOBAL, so this ran on a private MySQL 9.7.2 524 container on the same machine, restarted cold:

Rewriting a monthly report step by step, measured by the slow query logSQL
q="SELECT c.country, SUM(oi.quantity * oi.unit_price) AS revenue FROM orders AS o
   JOIN customers AS c ON c.id = o.customer_id JOIN order_items AS oi ON oi.order_id = o.id
   WHERE o.status <> 'cancelled' AND"
g="GROUP BY c.country ORDER BY revenue DESC"
sudo mysql shop -e "SET GLOBAL slow_query_log_file = '/var/lib/mysql/slow.log',
                    slow_query_log = ON, long_query_time = 0.05"
sudo mysql shop -e "$q DATE_FORMAT(o.ordered_at, '%Y-%m') = '2026-08' $g" > /dev/null
sudo mysql shop -e "ALTER TABLE orders ADD INDEX idx_ordered_at (ordered_at)"
sudo mysql shop -e "$q DATE_FORMAT(o.ordered_at, '%Y-%m') = '2026-08' $g" > /dev/null
sudo mysql shop -e "$q o.ordered_at >= '2026-08-01' AND o.ordered_at < '2026-09-01' $g" > /dev/null
sudo grep '^# Query_time' /var/lib/mysql/slow.log
Output
# Query_time: 0.454882  Lock_time: 0.000036 Rows_sent: 10  Rows_examined: 551687
# Query_time: 0.235647  Lock_time: 0.000004 Rows_sent: 10  Rows_examined: 551687
# Query_time: 0.119962  Lock_time: 0.000002 Rows_sent: 10  Rows_examined: 67256

The report covers 14,811 orders, yet the first version examined 551,687 rows. The index alone changed only the cache temperature: DATE_FORMAT() hides the column and its selectivity (the optimizer expected about 370,000 matches), and in an earlier run it even switched to driving from customers (1.34 s). The sargable range examined 67,256 rows in 0.12 s. The loop is always the same: find the statement in the slow log (Slow Query Log), EXPLAIN ANALYZE it, find where actual rows explode, change one thing, measure.