MySQL和跳过WHERE谓词

MySQL和跳过WHERE谓词,mysql,Mysql,如果下面的last_name为NULL,它会跳过该列上的WHERE比较以提高性能吗 AND (last_name IS NULL OR sp.last_name LIKE CONCAT('%',IFNULL(last_name, ''),'%')) MySQL可以按任意顺序执行比较 它很可能会首先执行NULL检查,因为它的计算速度更快,但这并不能保证。据我所知,这是正确的,它将包含行而不计算后一个表达式。但是,这可以(应该?)用已知的数据集进行测试,方法是让后一个表达式产生副作用(例如递增计数

如果下面的last_name为NULL,它会跳过该列上的WHERE比较以提高性能吗

AND (last_name IS NULL OR sp.last_name LIKE CONCAT('%',IFNULL(last_name, ''),'%'))

MySQL可以按任意顺序执行比较


它很可能会首先执行
NULL
检查,因为它的计算速度更快,但这并不能保证。

据我所知,这是正确的,它将包含行而不计算后一个表达式。但是,这可以(应该?)用已知的数据集进行测试,方法是让后一个表达式产生副作用(例如递增计数器),并在针对last_name列中只有NULL的数据集运行计数器之前和之后检查计数器

编辑:已测试v5.5.25 对于好奇的人:

+------+
| name |
+------+
| NULL |
+------+
| Bill |
+------+
下面的每个查询前面都有
set@foo=0
,然后根据
的结果选择@foo将显示

SELECT name FROM names WHERE (@foo:=@foo+1 OR name IS NULL);
-- 1 (did optimize) - same without parenthesis

SELECT name FROM names WHERE name IS NULL OR (@foo:=@foo+1);
-- 1 (did optimize)

SELECT name FROM names WHERE (@foo:=@foo+1) OR name IS NULL;
-- 2 (did not optimize)
有趣的是,我无法生成一个没有以这种方式优化的更新查询。i、 e.无论我在where子句中如何安排这两个表达式,它总是只增加@foo一次。

试试这个:

AND  (if(last_name is null,1, sp.last_name 
LIKE CONCAT('%',last_name,'%')))

如果它碰巧选择了空值,它会跳过第二次比较,对吗?出于好奇,您是否确实尝试过更简单的
WHERE sp.last_name,如CONCAT('%,last_name,'%'))
,您似乎在回避它?结果可能不像你担心的那么慢……我有,而且查询时间略有增加。@MikeFlynn,根据测试(未记录),MySQL确实执行短路评估,但正如Mark所解释的,这是在经过优化器之后完成的,优化器将按其决定的顺序执行评估,顺序可能会改变(例如,它可以是任何顺序)。姓不是空的吗?或者…
在这里是多余的吗?我的意思是不必要的冗余和不必要的重复。我同意这不是多余的吗?我想是的,我只是把代码的重要部分,放在OR之后,是需要修复的重要事情。我只是去掉了那个部分,我刚刚试过这个,它实际上增加了时间。我平均得到了1.17秒,这将它引导到1.2秒。这被称为“短路”评估。如果你在上面搜索,你会发现更多的结果。我运行了一些可能感兴趣的测试,结果在下面我的答案中。