Function Order Optimization
Learn how the order of functions in WHERE clauses affects query performance.
Note: Modern database query optimizers are increasingly sophisticated and may automatically apply many of these optimizations regardless of how the query is written. Always test with EXPLAIN or EXPLAIN ANALYZE for your specific database and data distribution.
The order of functions in WHERE clauses and how functions are applied can significantly impact query performance. Understanding these patterns helps write more efficient queries.
1. Function on Column vs. Constant
Before (Inefficient Query)
SELECT *
FROM users
WHERE LOWER(username) = 'john';
After (Optimized Query)
SELECT *
FROM users
WHERE username = LOWER('John');
2. Order of Nested Functions
Before (Inefficient Query)
SELECT *
FROM users
WHERE LOWER(TRIM(username)) = 'john';
After (Optimized Query)
SELECT *
FROM users
WHERE username = TRIM(LOWER(' John '));
3. Functions in LIKE
Before (Inefficient Query)
SELECT *
FROM users
WHERE LOWER(username) LIKE 'john%';
After (Optimized Query)
SELECT *
FROM users
WHERE username LIKE 'john%' COLLATE NOCASE;
4. Arithmetic Expression Order
Before (Inefficient Query)
SELECT *
FROM orders
WHERE (price * quantity) > 100;
After (Optimized Query)
SELECT *
FROM orders
WHERE price > 100 / quantity;
5. Functions in JOIN Condition
Before (Inefficient Query)
SELECT * FROM users u
JOIN orders o
ON LOWER(u.email) = LOWER(o.email);
After (Optimized Query)
SELECT * FROM users u
JOIN orders o
ON u.email = o.email;
6. WHERE Clause Order (Short-Circuiting)
Before (Inefficient Query)
SELECT *
FROM users
WHERE LOWER(username) = 'john'
AND is_active = 1;
After (Optimized Query)
SELECT *
FROM users
WHERE is_active = 1
AND LOWER(username) = 'john';
7. Functional Index
If you frequently query with a function, consider creating a functional index:
Before (Inefficient Query)
SELECT *
FROM users
WHERE LOWER(username) = 'john';
After (Optimized Query)
-- Create functional index
CREATE INDEX idx_users_lower_username
ON users(LOWER(username));
-- Now this can be fast
SELECT *
FROM users
WHERE LOWER(username) = 'john';
8. Multiple Functions Per Row
Before (Inefficient Query)
SELECT *
FROM products
WHERE LENGTH(TRIM(name)) > 10;
After (Optimized Query)
SELECT *
FROM products
WHERE name > ' ';
Best Practices
- Apply functions to constants, not columns -
column = FUNCTION('value')is better thanFUNCTION(column) = 'value' - Minimize nested functions - Apply functions once to constants rather than multiple times to columns
- Use COLLATE for case-insensitive matching - Avoid LOWER() on columns when possible
- Rearrange arithmetic expressions - Move column operations to one side of comparisons
- Avoid functions on JOIN columns - Functions prevent index usage in JOINs
- Put selective conditions first - Highly selective conditions should come first for short-circuit evaluation
- Consider functional indexes - If you must use functions, index them