I did some experimenting. Here's my guess:
WHERE (constant-expression-evaluating-to-FALSE)
AND (SELECT ...)
It will evaluate the constant and stop.
WHERE (col ... ) -- some test that can't use an index (but always fails)
AND (SELECT ...)
It will evaluate the SELECT
. Here the Optimizer is being smart -- it realizes that reevaluating the SELECT
is likely to be costly, so better to do it once. Actually, the EXPLAIN FORMAT=JSON
says "optimized_away_subquery", which probably means that, in the process of deciding what to do with the subquery, it evaluated it.
Note that I am assuming that the subquery is not correlated. That is, nothing from the original table is referenced in it. If it were, then the Optimizer would be obligated to evaluate it for each row in the outer query. And it would probably go back to the original case -- always FALSE would avoid evaluating the subquery. However, multiple TRUEs would lead to multiple evaluations.
(I arrived at this by (1) somewhat understanding the Optimizer, and (2) testing. Caveat: My test was with 5.6.22; older versions, and MariaDB may work differently. However, I believe that 5.7 and 8.0 will work the same.)
&&
operator returns false if the first condition is false, and does not evaluate the second, or after, condition(s). Does MySQL do that, if evaluating from left to right, or will it continue to evaluate the whole expression?