I hope this is my last post about this topic. It seems we've
resolved all of the issues and I'll now describe the user-visible
consequences.
To recall, we're talking about subquery predicates in form
(oe1, ..., oeN) [NOT] IN (SELECT ie1, ..., ieN FROM ... )
that are located in a context where it matters if the predicate's result is NULL or FALSE. The name "oe" stands for "outer expression", ie stands for "inner expression".
MySQL evaluates queries "from outside to inside", i.e. we first get the values of (oe1, .. oeN) and then we run the subquery and capture the rows it produces. An apparent and very useful optimization is to "inform" the subquery that we're looking only for rows that have "ie1=oe1", "ie2=oe2" and so on. This is done by injecting appropriate equalities into subquery's WHERE (or HAVING) clause. That is,
(oe1, ..., oeN) [NOT] IN (SELECT ie1, ..., ieN FROM ... )
becomes …
[Read more]