Indexing an expression required adding a generated column and indexing that, which means a schema change and a column nobody wants in a SELECT *.
-- 8.0.13
ALTER TABLE orders ADD INDEX idx_year ((YEAR(placed_at)));
ALTER TABLE customers ADD INDEX idx_email_lower ((LOWER(email)));
-- the query has to match the expression EXACTLY
SELECT * FROM orders WHERE YEAR(placed_at) = 2020; -- uses it
SELECT * FROM orders WHERE placed_at >= '2020-01-01'; -- does not
The double parentheses are required and their absence is a confusing syntax error. The expression in the query must match the indexed one exactly, which is stricter than people expect — YEAR(placed_at) and EXTRACT(YEAR FROM placed_at) are the same value and different expressions. For a date range the better answer remains a plain index on the column and a range predicate, which is faster and does not need this at all.