第八章 优化(十六)—— IS NULL 优化
8.2 优化SQL语句
8.2.1 优化 SELECT 语句
8.2.1.15 IS NULL 优化
MySQL对col_name IS NULL
执行时采用的优化可以与执行col_name = constant_value
时相同。例如,MySQL可以使用索引和范围来搜索条件中带 IS NULL
的数据值NULL
。
示例:
SELECT * FROM tbl_name WHERE key_col IS NULL;
SELECT * FROM tbl_name WHERE key_col <=> NULL; # <=> 会严格比较两个NULL值是否相等
SELECT * FROM tbl_name
WHERE key_col = const1 OR key_col = const2 OR key_col IS NULL;
如果WHERE子句包含col_name IS NULL
条件,而该列声明为 NOT NULL
,则该表达式将被优化掉。如果该列可能会在执行中产生NULL
(例如,如果它来自左连接的右侧表),则不会发生这种优化。(译者:col_name 列名,expr 表达式)
MySQL还可以优化这个组合col_name = expr OR col_name IS NULL
,这种形式在已解析的子查询中很常见。如果这种优化得到应用,则EXPLAIN显示ref_or_null
(译者:引用或空)。
这种优化可以对任何键部分处理一个 IS NULL
级别。
假设表t2的a列和b列上有一个索引,一些优化的查询示例如下:
SELECT * FROM t1 WHERE t1.a = expr OR t1.a IS NULL;
SELECT * FROM t1, t2 WHERE t1.a = t2.a OR t2.a IS NULL;
SELECT * FROM t1, t2
WHERE (t1.a = t2.a OR t2.a IS NULL) AND t2.b = t1.b;
SELECT * FROM t1, t2
WHERE t1.a = t2.a AND (t2.b = t1.b OR t2.b IS NULL);
SELECT * FROM t1, t2
WHERE (t1.a = t2.a AND t2.a IS NULL AND ...)
OR (t1.a = t2.a AND t2.a IS NULL AND ...);
ref_or_null
的工作原理是:首先读取引用键,然后单独搜索具有NULL
键值的行。
该优化只能处理一个 IS NULL
级别。在下面的查询中,MySQL只在表达式 (t1.a = t2.a AND t2.a IS NULL)
上使用键进行查找,而不能在b上使用键部分:
SELECT * FROM t1, t2
WHERE (t1.a = t2.a AND t2.a IS NULL)
OR (t1.b = t2.b AND t2.b IS NULL);