oracle exists mysql_关于ORACLE MYSQL NOT IN和NOT exists需要注意的 NULL值

首先说明NOT IN 和NOT EXISTS 并不完全等价 ORACLE MYSQL 都是如此

源表:

SQL> select * from testa1;

NAME                          ID

-------------------- -----------

gaopeng                        1

gaopeng                        2

gaopeng                        3

gaopeng                        4

SQL> select * from testb1;

NAME                          ID

-------------------- -----------

gaopeng                        1

gaopeng                        2

gaopeng

因为NOT IN是对NULL 敏感的而NOT  exists却不是,所以ORACLE使用的执行计划如下:

select * from testa1 where  not exists (select * from testb1 where testa1.id=testb1.id );

NAME                          ID

-------------------- -----------

gaopeng                        4

gaopeng                        3

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 4225223740

-----------------------------------------------------------------------------

| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |        |     4 |   152 |     5  (20)| 00:00:01 |

|*  1 |  HASH JOIN ANTI    |        |     4 |   152 |     5  (20)| 00:00:01 |

|   2 |   TABLE ACCESS FULL| TESTA1 |     4 |   100 |     2   (0)| 00:00:01 |

|   3 |   TABLE ACCESS FULL| TESTB1 |     3 |    39 |     2   (0)| 00:00:01 |

普通的反连接

select * from testa1 where  testa1.id not in (select testb1.id from testb1  );

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 2176127487

-----------------------------------------------------------------------------

| Id  | Operation          | Name   | Rows  | Bytes | Cost (%CPU)| Time     |

-----------------------------------------------------------------------------

|   0 | SELECT STATEMENT   |        |     4 |   152 |     5  (20)| 00:00:01 |

|*  1 |  HASH JOIN ANTI NA |        |     4 |   152 |     5  (20)| 00:00:01 |

|   2 |   TABLE ACCESS FULL| TESTA1 |     4 |   100 |     2   (0)| 00:00:01 |

|   3 |   TABLE ACCESS FULL| TESTB1 |     3 |    39 |     2   (0)| 00:00:01 |

-----------------------------------------------------------------------------

11g后改良的HASH JOIN ANTI NA 连接方式如果我们改变优化器到9I其执行计划为

select /*+ optimizer_features_enable('9.2.0') */ * from testa1 where  testa1.id not in (select testb1.id from testb1  );

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 1097631637

-------------------------------------------------------------

| Id  | Operation          | Name   | Rows  | Bytes | Cost  |

-------------------------------------------------------------

|    0 | SELECT STATEMENT   |        |     4 |   100 |     4 |

|*   1 |  FILTER            |        |       |       |       |

|     2 |   TABLE ACCESS FULL| TESTA1 |     4 |   100 |     2 |

|*   3 |   TABLE ACCESS FULL| TESTB1 |    78 |  1014 |     2 |

-------------------------------------------------------------

可以看到老的执行计划是用不了的。

关于MYSQL 我也实验了一样和ORACLE一样 其执行计划如下:

mysql> explain select * from testa1 where  testa1.id not in (select testb1.id from testb1  );

+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

| id | select_type | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |

+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

|  1 | PRIMARY     | testa1 | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |

|  2 | SUBQUERY    | testb1 | ALL  | NULL          | NULL | NULL    | NULL |    3 | NULL        |

+----+-------------+--------+------+---------------+------+---------+------+------+-------------+

2 rows in set (0.00 sec)

mysql> explain select * from testa1 where  not exists (select * from testb1 where testa1.id=testb1.id );

+----+--------------------+--------+------+---------------+------+---------+------+------+-------------+

| id | select_type        | table  | type | possible_keys | key  | key_len | ref  | rows | Extra       |

+----+--------------------+--------+------+---------------+------+---------+------+------+-------------+

|  1 | PRIMARY            | testa1 | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |

|  2 | DEPENDENT SUBQUERY | testb1 | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |

+----+--------------------+--------+------+---------------+------+---------+------+------+-------------+

当然 in 和 exists 是等价的

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-1588867/,如需转载,请注明出处,否则将追究法律责任。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值