Optimizing
SELECT
Statements
681
The conversion just described has its limitations. It is valid only if we ignore possible
NULL
values. That
is, the “pushdown” strategy works as long as both of these two conditions are true:
•
outer_expr
and
inner_expr
cannot be
NULL
.
• You do not need to distinguish
NULL
from
FALSE
subquery results. (If the subquery is a part of an
OR
[881]
or
AND
[880]
expression in the
WHERE
clause, MySQL assumes that you don't care.)
When either or both of those conditions do not hold, optimization is more complex.
Suppose that
outer_expr
is known to be a non-
NULL
value but the subquery does not produce a row
such that
outer_expr
=
inner_expr
. Then
outer_expr IN (SELECT ...)
evaluates as follows:
•
NULL
, if the
SELECT
produces any row where
inner_expr
is
NULL
•
FALSE
, if the
SELECT
produces only non-
NULL
values or produces nothing
In this situation, the approach of looking for rows with
outer_expr = inner_expr
is no longer valid.
It is necessary to look for such rows, but if none are found, also look for rows where
inner_expr
is
NULL
. Roughly speaking, the subquery can be converted to:
EXISTS (SELECT 1 FROM ... WHERE
subquery_where
AND
(
outer_expr
=
inner_expr
OR
inner_expr
IS NULL))
The need to evaluate the extra
IS NULL
[877]
condition is why MySQL has the
ref_or_null
[647]
access method:
mysql>
EXPLAIN
->
SELECT outer_expr IN (SELECT t2.maybe_null_key
->
FROM t2, t3 WHERE ...)
-> FROM t1;
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t1
...
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: t2
type: ref_or_null
possible_keys: maybe_null_key
key: maybe_null_key
key_len: 5
ref: func
rows: 2
Extra: Using where; Using index
...
The
unique_subquery
[647]
and
index_subquery
[647]
subqery-specific access methods also
have or-null variants. However, they are not visible in
EXPLAIN
output, so you must use
EXPLAIN
EXTENDED
followed by
SHOW WARNINGS
(note the
checking NULL
in the warning message):
mysql>
EXPLAIN EXTENDED
->
SELECT outer_expr IN (SELECT maybe_null_key FROM t2) FROM t1\G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t1
...
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: t2
type: index_subquery
possible_keys: maybe_null_key
key: maybe_null_key
key_len: 5
Summary of Contents for 5.0
Page 1: ...MySQL 5 0 Reference Manual ...
Page 18: ...xviii ...
Page 60: ...40 ...
Page 396: ...376 ...
Page 578: ...558 ...
Page 636: ...616 ...
Page 844: ...824 ...
Page 1234: ...1214 ...
Page 1427: ...MySQL Proxy Scripting 1407 ...
Page 1734: ...1714 ...
Page 1752: ...1732 ...
Page 1783: ...Configuring Connector ODBC 1763 ...
Page 1793: ...Connector ODBC Examples 1773 ...
Page 1839: ...Connector Net Installation 1819 2 You must choose the type of installation to perform ...
Page 2850: ...2830 ...
Page 2854: ...2834 ...
Page 2928: ...2908 ...
Page 3000: ...2980 ...
Page 3122: ...3102 ...
Page 3126: ...3106 ...
Page 3174: ...3154 ...
Page 3232: ...3212 ...