`
liulanghan110
  • 浏览: 1076609 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

in和exists

 
阅读更多

先创建测试数据 :

create table student
(
   
id int primary key not null ,
   
sid   int
)

          create table test
(
   
id int primary key not null ,
   
sid   int
)

create procedure insertDate()
BEGIN
     DECLARE v_id int;
     set v_id = 0;
     while v_id < 100000
     DO
       insert into student values(v_id,v_id );
       set v_id = v_id + 1;
     end while;
END
;

-- 插入数据

         call insertDate ()

insert into test select * from student where sid < 100

 

-- 更新统计信息

runstats on table nbadv . student with distribution and detailed indexes all

runstats on table nbadv . test with distribution and detailed indexes all

 

1 、主查询小表,子查询大表

测试 in exists

select * from test a where a . sid in ( select sid from  student )

select * from test a where exists ( select b . sid from student b where b . sid = a . sid )

执行计划相同,如下:

 

 

可以看到 in exists 都是将两个表进行连接,然后选择满足条件的记录。而且可以看到,这里使用的是嵌套循环连接( Nest   Loop Join ,简写 NLJOIN

 

测试 not in not exists

select * from test a where a . sid not in ( select sid from  student )

 

 



 select

 

 

* from test a where not exists ( select b . sid from student b where b . sid = a . sid )



 

 

可以看到 not in 的左边比右边多一步,而 not exists 的右边比左边多一步。 NOT IN 是自内向外的操作,即先得到子查询的结果,然后执行最外层的查询,而 NOT EXISTS 恰好相反,是自外向内的操作 .

2 、主查询大表,子查询小表

select * from student a where a . sid in ( select sid from  test )

select * from student a where exists ( select b . sid from test b where b . sid = a . sid )

执行计划相同 , 如下:



  

可以看到 in exists 都是将两个表进行连接,然后选择满足条件的记录。而且可以看到,这里使用的是嵌套循环连接( Nest   Loop Join ,简写 NLJOIN

 

select * from student a where a . sid not in ( select sid from  test )



 

select * from student a where not exists ( select b . sid from test b where b . sid = a . sid )



 

 

可以看到 not in 会取出主表的每一条记录,然后扫描从表,找出结果。而 not exists 是连接两个表找出记录,这里采用的是嵌套循环连接 (NLJOIN)

3 、主查询大表,子查询大表

select * from student a where a . sid in ( select sid from  student )

select * from student a where exists ( select b . sid from student b where b . sid = a . sid )

执行计划一样,如下图:



 

可以看到 in exists 都是将两个表进行连接,然后选择满足条件的记录。而且可以看到,这里使用的是哈希连接( Hash Join ,简写 HSJOIN

select * from student a where a . sid not in ( select sid from  student )



 

 

 

select * from student a where not exists ( select b . sid from student b where b . sid = a . sid )



 

 

可以看到 not in 会取出主表的每一条记录,然后扫描从表,找出结果。而 not exists 是连接两个表找出记录,这里采用的是嵌套循环连接 (NLJOIN)

4 、主查询小表,子查询小表

select * from test a where a . sid in ( select sid from  test )

select * from test a where exists ( select b . sid from test b where b . sid = a . sid )

执行计划一样,如下图:



 

 

select * from test a where a . sid not in ( select sid from  test )




 
 

select * from test a where not exists ( select b . sid from test b where b . sid = a . sid )

 



 

in exists 效率分析 :

    当主表大表,从表是小表时, 103.54, 且都是嵌套循环连接 (NLJOIN)

当主表小表,从表是大表时, 109.96, 且都是嵌套循环连接 (NLJOIN)

当主表大表,从表是大表时, 1821.93, 且都是哈希连接( Hash Join ,简写 HSJOIN

当主表小表,从表是小表时, 128.74, 且都是哈希连接( Hash Join ,简写 HSJOIN

可以看出 in exists 速度一样,且都是得到两边查询结果后(主查询结果和子查询结果)进行表连接来得到结果,至于采用哪种连接方式系统会自动选择。总之, in exists 效率是一样的。

not in 效率分析 :

    当主表大表,从表是小表时, 1332.85

当主表小表,从表是大表时, 4090.92

当主表大表,从表是大表时, 270913.84

当主表小表,从表是小表时, 131.87

可以看出主查询的结果是大表时,子查询的记录由小变大时,效率降低了 270913.84/1332.85 =203 ,也可以看出主查询的结果是小表时,子查询的记录由小变大时,效率几乎没变。

所以影响 not in 的主要是主查询表的大小。

not exists 效率分析 :

    当主表大表,从表是小表时, 103.54

当主表小表,从表是大表时, 973.35

当主表大表,从表是大表时, 1822.34

当主表小表,从表是小表时, 128.74  

可以看到表的大小对 not exists 没什么影响。另外,可以发现, not exists exists 效率几乎一样。

注:以上测试都是在比较列有索引的情况下进行的。

总结:

in exists 效率一样,用哪个都可以。但是一般来说, not exists not in 速度快(在 not exists 子查询里的语句比较复杂时,有可能比 not in 慢), 最好将 not in 转化成 not exists 。另外,要注意的是 ,in 或者 not in 里面都不能有 null 值,否则会得不到结果。

  • 大小: 33.9 KB
  • 大小: 26 KB
  • 大小: 20.2 KB
  • 大小: 30.6 KB
  • 大小: 30 KB
  • 大小: 23.5 KB
  • 大小: 19.8 KB
  • 大小: 21.7 KB
  • 大小: 20 KB
  • 大小: 43 KB
  • 大小: 25.9 KB
  • 大小: 44.1 KB
分享到:
评论

相关推荐

    in和exists的区别

    在Oracle数据库中,"IN"和"EXISTS"都是用于查询某个集合的元素是否存在于另一个集合中的关键字。然而,它们在处理数据时的效率和适用场景有所不同,这主要取决于涉及的数据量以及表之间的关联。 首先,让我们来看看...

    in和exists的区别与执行效率问题解析

    标题和描述均聚焦于SQL查询语句中"IN"与"EXISTS"的区别及执行效率问题,这是一个在数据库操作中非常关键的话题,尤其对于优化查询性能有着不可忽视的作用。下面,我们将深入探讨这两种语句的不同之处及其对执行效率...

    in和exists性能解析

    在数据库查询语言中,`IN` 和 `EXISTS` 子句是两种常见的用于关联两个表的方法,它们各自有其独特的性能特点和适用场景。本文将深入解析Oracle中`IN`与`EXISTS`的性能差异,以及如何根据具体需求选择最合适的查询...

    sql in,exists,not in,not exists区别

    IN、EXISTS、NOT IN、NOT EXISTS 是 SQL 中四种常用的条件判断运算符,它们之间的区别主要体现在使用场景、执行效率和语法结构上。 IN IN 是一种条件判断运算符,用于判断某个值是否存在于一个列表中。其基本语法...

    简述Oracle中in和exists的不同

    如果两张表大小差不多,那么exists和in的效率差不多。 例如: 一张大表为A,一张小表B 一、第一种情况 select * from A where mm in (select mm from B) 效率高,这里用到的是大表A上的索引 select * from B ...

    “exists”和“in”的效率问题

    ### "Exists"与"In"的效率问题详解 #### 引言 在数据库查询语言SQL中,“Exists”与“In”是两种常用的子查询方法,它们在实际应用中各有优势与局限。本文将深入探讨这两种方法的工作原理、应用场景以及性能差异,...

    Oracle In和exists not in和not exists的比较分析

    在Oracle数据库中,`IN`、`EXISTS`、`NOT IN` 和 `NOT EXISTS` 是四个常用的子查询操作符,它们在SQL查询语句中扮演着不同的角色,且各有其性能特点。以下是对这些操作符的详细分析和比较。 1. `IN` 操作符: `IN` ...

    sql中exists的用法

    在 SQL 中,in 和 exists 的使用场景可以互换,但是在某些情况下,exists 的效率可能要高于 in。例如: ```sql SELECT ID, NAME FROM A WHERE ID IN (SELECT AID FROM B); ``` 这个查询将返回表 A 中所有与表 B 相...

    oracle中exists_和in的效率问题详解

    Oracle 中 EXISTS 和 IN 的效率问题详解 EXISTS 和 IN 都是 Oracle 中的集合操作符,但它们在使用和执行效率上有所不同。本文将深入探讨 EXISTS 和 IN 的使用场景、执行机制和效率问题。 EXISTS 的使用场景和机制 ...

    SQL查询中in和exists的区别分析

    在SQL查询中,`IN` 和 `EXISTS` 是两种常用的子查询操作符,它们用于在主查询中筛选满足特定条件的记录。然而,它们在处理大数据量时的效率和性能有着显著的区别。 首先,`IN` 操作符的工作原理是先从子查询中获取...

    MySQL中的in,exists,not in,not exists查询过程对比及结论

    MySQL优化之in,exists,not in,not exists的区别in与existsin查询过程结论:exists查询过程:结论:not in与not existsnot in查询过程:结论:not exists查询过程:结论: 首先我们使用两个用户表作为实例 insert ...

    SQL里的EXISTS与IN

    在SQL查询语言中,`EXISTS` 和 `IN` 子句都是非常常用且重要的操作符,它们被广泛应用于复杂的查询条件中,特别是当需要检查某个子查询是否返回结果时。根据给定的信息,本文将详细解析`EXISTS`与`IN`的区别以及如何...

    SQL语句优化——in,not in,exists,not exists, left join...on博客所需SQL语句.txt

    SQL语句优化——in,not in,exists,not exists, left join...on博客所需SQL语句.txt欢迎下载!

    PostgreSQL IN vs EXISTS vs ANYALL vs JOIN性能分析

    PostgreSQL作为一种强大的开源关系数据库系统,它支持多种SQL操作,其中包括IN、EXISTS、ANY/ALL和JOIN等操作符。这些操作符在不同的业务场景下有着不同的表现和性能影响。在实际的数据库操作中,选择合适的操作符是...

    sql case when exists not exists in not in

    在SQL查询中,`CASE WHEN`、`EXISTS`、`NOT EXISTS`以及`IN`和`NOT IN`是常用的操作符,它们用于处理复杂的条件判断和数据筛选。这些概念对于理解和编写高效的SQL语句至关重要,尤其是在数据分析和数据库管理中。 `...

Global site tag (gtag.js) - Google Analytics