MySQL对条件化简规则,有些支持,有些不支持,情况如表14-3所示。
表14-3 MySQL支持的表达式化简对照表
规则 | 表达式原型 | 支持 |
把HAVING子句并入WHERE子句 |
| 不支持(MySQL的WHERE和HAVING子句分别独立处理) |
去除表达式中冗余的括号 | ((a AND b)AND (c AND d)) | 支持 |
常量传递 | col_1 = col_2 AND col_2 = 3 | 支持 |
消除死码 | (0 > 1 OR a = 5) | 支持 |
表达式计算 | col_1 = 1 + 2 | 部分支持 如果是操作数都是常量则能计算求值;如果操作数中有变量则能计算求值 |
等式变换 | -a = 3 | 不支持 |
不等式变换 | a > 10 AND b = 6 AND a > 2 | 不支持 |
谓词传递闭包 | a>b AND b>2 | 不支持 |
合取项只要有一个为假,即整个表达式为假 | (0 > 1 AND s1 = 5) | 支持 |
AND操作符是可交换的 | col_2+col_1=100 AND col_2>1 AND col_1>2
| 支持 MySQL支持对条件按表连接的次序进行排序,优先判断连接的表涉及的条件 |
示例1 如果表达式中没有变量,则可以对表达式求值,查询执行计划如下:
mysql> EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE 0>1+2 AND a1=10;
+----+-------------+-------+------+------------------+
| id | select_type | table | type | Extra |
+----+-------------+-------+------+------------------+
| 1 | SIMPLE | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+------------------+
被查询优化器处理后的语句为:
/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,
`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2`
from `test`.`t1` join `test`.`t2`
where 0
从查询执行计划看,“0>1+2”被求值为FALSE,“FALSE AND a1=10”值是FALSE,所以WHERE子句的值为“0”。
示例2 如果表达式中有变量,则不可以对表达式求值,查询执行计划如下:
mysql> EXPLAIN EXTENDED SELECT * FROM t1, t2 WHERE a2>1+2 AND a1=10;
+----+-------------+-------+----------------------------------------------------
| id | select_type | table | Extra |
+----+-------------+-------+---------------------------------------------------
| 1 | SIMPLE | t1 | NULL
| 1 | SIMPLE | t2 | Using index condition; Using join buffer (Block Nested Loop) |
+----+-------------+-------+---------------------------------------------------
被查询优化器处理后的语句为:
/* select#1 */ select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,
`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2`
from `test`.`t1` join `test`.`t2`
where ((`test`.`t1`.`a1` = 10) and (`test`.`t2`.`a2` > (1 + 2)))