1. MySQL's optimizer can recognize expressions: mysql> create table t1 (a int, b int, c int generated always as (a+1)); mysql> alter table t1 add key(c); mysql> insert into t1 (a,b) select a,a from one_k; mysql> explain select * from t1 where (a+1) =1; +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+ | 1 | SIMPLE | t1 | NULL | ref | c | c | 5 | const | 1 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0,00 sec) mysql> explain select * from t1 where (a+1) <1; +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | range | c | c | 5 | NULL | 1 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0,00 sec) mysql> explain select * from t1,ten where (t1.a+1)=ten.a; +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------------------------+ | 1 | SIMPLE | ten | NULL | index | PRIMARY | PRIMARY | 4 | NULL | 10 | 100.00 | Using index | | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | Using where; Using join buffer (hash join) | +----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------------------------+ 2 rows in set, 1 warning (0,01 sec) #2. But join queries are not recognized create table t0 as select * from ten; alter table t0 add primary key(a); alter table t0 add b int; mysql> explain select * from t1,t0 where (t1.a+1)=t0.b and t0.a=1; +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | t0 | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | | 1 | SIMPLE | t1 | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | Using where | +----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ 2 rows in set, 1 warning (0,00 sec) # 3. in the trace, it is "substitute_generated_columns" mysql> explain select * from t1 where (a+1) <1; { "substitute_generated_columns": { "resulting_condition": "(`t1`.`c` < 1)" } }, # 4. What if there are multiple ways one can substitute? mysql> alter table t1 add column c1 int generated always as (a+1); mysql> alter table t1 add index(c1, b); mysql> show create table t1; CREATE TABLE `t1` ( `a` int DEFAULT NULL, `b` int DEFAULT NULL, `c` int GENERATED ALWAYS AS ((`a` + 1)) VIRTUAL, `c1` int GENERATED ALWAYS AS ((`a` + 1)) VIRTUAL, KEY `c` (`c`), KEY `c1` (`c1`,`b`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; mysql> explain select * from t1 where (a+1) =1 and b=2; +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | t1 | NULL | ref | c | c | 5 | const | 1 | 10.00 | Using where | +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+ 1 row in set, 1 warning (0,00 sec) mysql> explain select * from t1 ignore index (c) where (a+1) =1 and b=2; +----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------+ | 1 | SIMPLE | t1 | NULL | ref | c1 | c1 | 10 | const,const | 1 | 100.00 | NULL | +----+-------------+-------+------------+------+---------------+------+---------+-------------+------+----------+-------+ 1 row in set, 1 warning (0,00 sec)