`

mysql in not in exist not exist 区别

阅读更多
Mysql In Not In 不对null 进行处理 如果子查询的结果集中出现NULL 那么 查询的结果集一定为 0 row

Exists Not Exists 会对Null 进行处理。

EXISTS语法并没有说哪个字段落在了子查寻的结果中,而是说exists后面的语句执行的结果是不是有记录,只要有记录,则主查询语句就成立。它代表‘存在’,用来引领嵌套查询的子查询,它不返回任何数据,只产生逻辑真值‘true’与逻辑假值‘False’。由EXISTS引出的子查询,其目标列表达式通常都用*(用null也可以),因为带有EXISTS的子查询只返回真值或假值,给出列名没有实际意义。
性能变化的关键:
#1 执行的先后顺序
谁是驱动表,谁先执行查询,谁后执行查询
#2 执行过程
exists的优点是:只要存在就返回了,这样的话很有可能不需要扫描整个表。 
in需要扫描完整个表,并返回结果。
所以,在字表比较小的情况下,扫描全表和部分表基本没有差别;但在大表情况下,exists就会有优势。
看这两个语句:
--子查询会执行完全关联,并返回所有符合条件的city_id
select * from areas where id in   (select city_id from deals where deals.city_id = areas.id);

--子查询的关联其实是一样的,但子查询只要查到一个结果,就返回了,所以效率还是比较高些的



select * from areas where exists (select null     from deals where deals.city_id = areas.id);

#3 字表查询的结果
exists判断子查询的结果是不是存在,但查到什么结果,什么字段,并不关心;
in      需要子查询查得的结果给主查询使用




in 和 Exists的用法区别
1.
EXISTS的执行流程       
select * from t1 where exists ( select null from t2 where y = x )
可以理解为:
    for x in ( select * from t1 )
    loop
       if ( exists ( select null from t2 where y = x.x )
       then
          OUTPUT THE RECORD
       end if
    end loop
对于in和exists的性能区别:
   如果子查询得出的结果集记录较少,主查询中的表较大且又有索引时应该用in,反之如果外层的主查询记录较少,子查询中的表大,又有索引时使用exists。
   其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询,所以我们会以驱动表的快速返回为目标,那么就会考虑到索引及结果集的关系了
                       
另外IN时不对NULL进行处理
如:
select 1 from dual where null  in (0,1,2,null)

2.NOT IN与NOT EXISTS:       
NOT EXISTS的执行流程
select .....
   from rollup R
where not exists ( select 'Found' from title T
                              where R.source_id = T.Title_ID);
可以理解为:
for x in ( select * from rollup )
       loop
           if ( not exists ( that query ) ) then
                  OUTPUT
           end if;
        end;

注意:NOT EXISTS与 NOT IN不能完全互相替换,看具体的需求。如果选择的列可以为空,则不能被替换。

例如下面语句,看他们的区别:
select x,y from t;
x               y
------          ------
1               3
3         1
1         2
1         1
3         1
5
select * from t where   x not in (select y from t t2   )
no rows
       
select * from t where   not exists (select null from t t2
                                                   where t2.y=t.x )
x        y
------   ------
5        NULL
所以要具体需求来决定

对于not in和 not exists的性能区别:
    not in只有当子查询中,select 关键字后的字段有not null约束或者有这种暗示时用not in,另外如果主查询中表大,子查询中的表小但是记录多,则应当使用not in,并使用anti hash join.
   如果主查询表中记录少,子查询表中记录多,并有索引,可以使用not exists,另外not in最好也可以用/*+ HASH_AJ */或者外连接+is null
NOT IN在基于成本的应用中较好

比如:
select .....
from rollup R
where not exists ( select 'Found' from title T
                            where R.source_id = T.Title_ID);

改成(佳)

select ......
from title T, rollup R
where R.source_id = T.Title_id(+)
     and T.Title_id is null;
                                 
或者(佳)
sql> select /*+ HASH_AJ */ ...
         from rollup R
         where ource_id NOT IN ( select ource_id
                                                from title T
                                               where ource_id IS NOT NULL )




问题和解决

问题1:



--users表有1000条记录,id自增,id都大于0

select * from users where exists (select * from users limit 0); --输出多少条记录?

select * from users where exists (select * from users where id < 0); --输出多少条记录?

答案(请选中查看):

10000条

0条

原因:

exists查询的本质,只要碰到有记录,则返回true;所以limit根本就不会去管,或者说执行不到。



问题2:

exists可以完全代替in吗?

不能。

例如:

--没有关联字段的情况:枚举常量

select * from areas where id in (4, 5, 6);

--没有关联字段的情况:这样exists对子查询,要么全true,要么全false

select * from areas where id in (select city_id from deals where deals.name = 'xxx');







举个相关exists的sql优化例子:

9、用exists替代in(发现好多程序员不知道这个怎么用):
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。
在这种情况下,使用exists(或not exists)通常将提高查询的效率。
举例:
(低效)
select ... from table1 t1 where t1.id > 10 and pno in (select no from table2 where name like 'www%');
(高效)
select ... from table1 t1 where t1.id > 10 and exists (select 1 from table2 t2 where t1.pno = t2.no and name like 'www%');
10、用not exists替代not in:
在子查询中,not in子句将执行一个内部的排序和合并。
无论在哪种情况下,not in都是最低效的 (因为它对子查询中的表执行了一个全表遍历)。
为了避免使用not in,我们可以把它改写成外连接(Outer Joins)或not exists。
11、用exists替换distinct:
当提交一个包含一对多表信息的查询时,避免在select子句中使用distinct. 一般可以考虑用exists替换
举例:
(低效)
select distinct d.dept_no, d.dept_name from t_dept d, t_emp e where d.dept_no = e.dept_no;
(高效)
select d.dept_no, d.dept_name from t_dept d where exists (select 1 from t_emp where d.dept_no = e.dept_no);
exists使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.
12、用表连接替换exists:
通常来说,采用表连接的方式比exists更有效率。
举例:
(低效)
select ename from emp e where exists (select 1 from dept where dept_no = e.dept_no and dept_cat = 'W');
SELECT ENAME
(高效)
select ename from dept d, emp e where e.dept_no = d.dept_no and dept_cat = 'W';

分享到:
评论

相关推荐

    The user specified as a definer ('root'@'%') does not exist 解决方法

    mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法

    mysql not in、left join、IS NULL、NOT EXISTS 效率问题记录

    MySQL中的`NOT IN`, `LEFT JOIN`, `IS NULL`, 和 `NOT EXISTS` 是四种不同的SQL查询方式,它们在特定情况下可以实现相似的功能,但实际执行效率可能会有很大差异。本文主要探讨这四种方法在处理大数据量时的性能表现...

    MySQL: mysql is not running but lock exists 的解决方法

    在使用MySQL数据库时,有时会遇到“MySQL is not running but lock exists”的错误,这通常意味着MySQL服务虽然没有运行,但系统中还存在一个锁文件,阻止了MySQL的正常启动。以下是一些解决此问题的步骤和相关的...

    sql语句优化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的语句

    SQL语句优化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的语句 SQL语句优化是数据库性能优化的重要方面之一。在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用EXISTS...

    mysql exists与not exists实例详解

    mysql exists与not exists实例详解 tableA |column1 | column1 |column3 | tableb |column1 | column1 |column3 | 要查询 tableA 的数据,条件是是 tableA.column1 不在 tableB 的 tableB.column2 中 也就是要得到...

    MySql报错Table mysql.plugin doesn’t exist的解决方法

    在MySQL数据库系统中,"Table mysql.plugin doesn’t exist" 是一个常见的错误,通常会在尝试启动MySQL服务时出现。这个错误表明MySQL服务器无法找到`mysql.plugin`表,该表是MySQL内部的一个关键组件,用于管理...

    MySQL部署时提示Table mysql.plugin doesn’t exist的解决方法

    最后,文章中还提到,安装和配置MySQL的过程可能因操作系统的不同而有所区别。例如,在Windows系统中,需要确保Windows防火墙或任何第三方安全软件都没有阻止MySQL端口(默认是3306)。同时,要确保在操作过程中,...

    Mysql:The user specified as a definer (‘xxx@’%’) does not exist的解决方案

    今天项目优化过程中,mysql有个问题The user specified as a definer (‘wx_root’@’%’) does not exist 查了一下,意思是执行sql无权限。 看了下数据库用户是quoters 而sql没有所属权。那就找原因了。发现sql执行...

    Mysql:The user specified as a definer ('xxx@'%') does not exist的解决方案

    在MySQL中,`The user specified as a definer ('xxx@'%') does not exist` 这个错误通常出现在尝试执行带有DEFINER语句的SQL对象(如存储过程、触发器或视图)时,DEFINER指定的用户不存在或者没有正确的权限。...

    mysql多表查询和EXISTS查询性能对比

    NOT EXISTS 是另一种排除条件查询的方式,其逻辑与NOT IN类似,但在某些情况下性能更优。NOT EXISTS 的SQL语法如下: ```sql SELECT * FROM tableA WHERE NOT EXISTS (SELECT 1 FROM tableB WHERE tableA.id = ...

    解决Mysql Error-The user specified as a definer (‘mysql.infoschema’

    在MySQL数据库操作中,"The user specified as a definer (‘mysql.infoschema’@’localhost’) does not exist" 是一个常见的错误提示,这通常发生在尝试执行存储过程、触发器或者视图等对象时,这些对象的定义者...

    搞懂mysql的exists

    3. 优先考虑`EXISTS`:在比较多个潜在查询方法时,`EXISTS`往往比其他方法(如`IN`、`NOT IN`)更快,特别是在大型数据集上。 六、实际应用示例 假设我们有两个表,`employees`和`departments`,我们想找出没有部门...

    MySQL exists 和in 详解及区别

    MySQL中的`EXISTS`和`IN`都是在SQL查询中用来检查某条记录是否符合特定条件的子查询操作符,但它们的工作原理和使用场景有所不同。 `EXISTS`子查询主要检查子查询是否能返回至少一行数据。在这个过程中,子查询的...

    MYSQL IN 与 EXISTS 的优化示例介绍

    `NOT IN` 和 `NOT EXISTS` 的用法类似于 `IN` 和 `EXISTS`,但它们用于查找不在特定子查询结果集中的记录。在优化这些操作时,同样遵循小表驱动大表的原则,并确保索引的存在。 ### 总结 选择 `IN` 还是 `EXISTS` ...

    mysql 计算字符串相似度

    ### MySQL 计算字符串相似度 #### 背景与需求 在许多应用场景中,我们需要对两个字符串进行相似度比较,比如搜索引擎中的关键词匹配、文本分析中的近义词识别等。MySQL 提供了多种方法来实现字符串相似度的计算,...

    SUSE 11 sp3 安装mysql 5.6

    - 在安装过程中可能会出现警告信息,例如“User mysql does not exist – using root”、“Group mysql does not exist – using root”。这些警告是因为安装程序未能找到 MySQL 用户和组,而使用了 root 来代替。...

    MySQL启动报错问题InnoDB:Unable to lock/ibdata1 error

    【MySQL启动报错问题InnoDB:Unable to lock/ibdata1 error】是一个常见的MySQL服务器启动时遇到的问题。这个问题通常表明MySQL的InnoDB存储引擎无法获取对`ibdata1`文件的锁,`ibdata1`是InnoDB用来存储数据和系统表...

    MYSQL5.0.41非安装版配置

    if not exist %windir%\my.ini goto MainNT if not exist c:\my.cnf goto MainNT :CopyINI echo Safethe %windir%\my.inias %windir%\my.ini.old! copy %windir%\my.ini /-y %windir%\my.ini.old del %windir%...

Global site tag (gtag.js) - Google Analytics