IS NULL 优化

来自泡泡学习笔记
BrainBs讨论 | 贡献2023年7月20日 (四) 05:57的版本 (创建页面,内容为“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; SELECT * FROM tbl_name WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL; 如果WHERE子句包括对一个声明为NOT NULL的列的col_name 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;

SELECT * FROM tbl_name
  WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL;


如果WHERE子句包括对一个声明为NOT NULL的列的col_name IS NULL条件,那么该表达式会被优化掉。但在某些情况下,当该列可能产生NULL值时(例如,如果它来自LEFT JOIN右侧的表),此优化不会发生。


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);