SQL 中 EXISTS 和 IN 语句的区别
由于查询时执行流程不同,因此在不同情况下查询效率各有优劣。
IN
确定给定的值是否与子查询或列表中的值相匹配。
IN 在查询的时候:
- 首先查询子查询的表,
- 然后将内表和外表做一个笛卡尔积,
- 然后按照条件进行筛选。
相对内表比较小的时候,IN 的速度较快。
EXISTS
指定一个子查询,检测行的存在。
EXISTS 在查询时:
- 首先,我们先查询的不是子查询的内容,而是查我们的主查询的表,
- 然后,根据表的每一条记录,执行 EXISTS 语句,依次去语句中的查询条件是否成立。
- 如果成立则返回 true 不成立则返回 false。如果返回的是 true 的话,则该行结果保留,如果返回的是 false 的话,则删除该行,最后将得到的结果返回。
区别和应用场景
IN 和 EXISTS 的区别:
- 如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用
in
- 反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用
exists
。
其实我们区分 IN 和 EXISTS 主要是造成了驱动顺序的改变(这是性能变化的关键),如果是 EXISTS,那么以外层表为驱动表,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了 ,另外 IN 时不对 NULL 进行处理。
IN 是把外表和内表作 HASH 连接,而 EXISTS 是对外表作 LOOP 循环,每次 LOOP 循环再对内表进行查询。一直以来认为 EXISTS 比 IN 效率高的说法是不准确的。
NOT IN 和 NOT EXISTS
- 如果查询语句使用了
NOT IN
,那么内外表都进行全表扫描,没有用到索引; - 而
NOT EXISTS
的子查询依然能用到表上的索引。
所以无论那个表大,用 NOT EXISTS
都比 NOT IN
要快。