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)))