8.2.1.8 IS NULL Optimization NULL 优化: Oracle 对待null值: SQL> create table t100(id int,name char(10)); 表已创建。 begin for i in 1 .. 1000 loop insert into t100 values(i,'a'||i); end loop; commit; end; BEGIN DBMS_STATS.GATHER_TABLE_STATS(ownname => 'SYS', tabname => 'T100', estimate_percent => 100, method_opt => 'for all columns size repeat', no_invalidate => FALSE, degree => 8, cascade => TRUE); END; / SQL> explain plan for select * from t100 where id=NULL; 已解释。 SQL> select * from table(dbms_xplan.display()); PLAN_TABLE_OUTPUT --------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- Plan hash value: 3750333395 --------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 15 | 0 (0)| | |* 1 | FILTER | | | | | | | 2 | TABLE ACCESS FULL| T100 | 1000 | 15000 | 3 (0)| 00:00:01 | --------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter(NULL IS NOT NULL) 已选择14行。 Oracle 索引不存储NULL值 MySQL 可以执行相同的优化在col_name IS NULL ,它可以使用col_name=常值。 MySQL 可以使用indexes 和ranges 来搜索NULL 使用IS NULL mysql> select * from t100 where id is NULL; +----+------+-------+------+ | sn | id | quota | free | +----+------+-------+------+ | 11 | NULL | xx | yy | +----+------+-------+------+ 1 row in set (0.00 sec) mysql> explain select * from t100 where id is NULL; +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ | 1 | SIMPLE | t100 | ref | t1oo_idx1 | t1oo_idx1 | 5 | const | 1 | Using index condition | +----+-------------+-------+------+---------------+-----------+---------+-------+------+-----------------------+ 1 row in set (0.00 sec) Oracle 里索引不存储NULL值,Mysql里索引包含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 子句包含一个col_name IS NULL 条件 对于一个列定义为NOT NULL, 那个表达式是优化掉的,这个优化不会发生 当列可能产生NULL,比如,如果它来自LEFT JOIN 右边的表 MySQL 也可以优化 组合 col_name = expr OR col_name IS NULL, 是解决子查询的常见形式, EXPLAIN 显示ref_or_null 当优化器被使用 mysql> explain select * from t100 where id=7 or id is NULL; +----+-------------+-------+-------------+---------------+-----------+---------+-------+------ +-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------------+---------------+-----------+---------+-------+------ +-----------------------+ | 1 | SIMPLE | t100 | ref_or_null | t1oo_idx1 | t1oo_idx1 | 5 | const | 2 | Using index condition | +----+-------------+-------+-------------+---------------+-----------+---------+-------+------ +-----------------------+ 1 row in set (0.00 sec) 优化器可以处理 IS NULL 对于任何索引部分