数据库sql语句的exists总结 sql exists in 学习

先来比较下语法:

--deals=交易表,areas=地域表,例如香港;我们的目的:查看有交易的地域

select * from areas where idin (select city_id from deals);

select * from areas where idin   (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);

区别:

EXISTS语法并没有说哪个字段落在了子查寻的结果中,而是说exists后面的语句执行的结果是不是有记录,只要有记录,则主查询语句就成立。它代表‘存在’,用来引领嵌套查询的子查询,它不返回任何数据,只产生逻辑真值‘true’与逻辑假值‘False’。由EXISTS引出的子查询,其目标列表达式通常都用*(用null也可以),因为带有EXISTS的子查询只返回真值或假值,给出列名没有实际意义。

性能变化的关键:

#1 执行的先后顺序

谁是驱动表,谁先执行查询,谁后执行查询

#2 执行过程

exists的优点是:只要存在就返回了,这样的话很有可能不需要扫描整个表。

in需要扫描完整个表,并返回结果。

所以,在字表比较小的情况下,扫描全表和部分表基本没有差别;但在大表情况下,exists就会有优势。

看这两个语句:

--子查询会执行完全关联,并返回所有符合条件的city_id

select * from areas where idin   (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 whereexists( select null from t2 where y = x )可以理解为:

for xin( 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 nullin(0,1,2,null)

2.NOTIN与NOTEXISTS:

NOTEXISTS的执行流程select .....

from rollup R

where notexists( select 'Found' from title T

where R.source_id = T.Title_ID);可以理解为:

for xin( select * from rollup )

loop

if ( notexists( that query ) ) then

OUTPUT

end if;

end;注意:NOTEXISTS与NOTIN不能完全互相替换,看具体的需求。如果选择的列可以为空,则不能被替换。例如下面语句,看他们的区别:select x,y from t;

x               y

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

1               3

3         1

1         2

1         1

3         1

5

select * from t where   x notin(select y from t t2   )

no rows

select * from t where   notexists(select null from t t2

where t2.y=t.x )

x        y

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

5        NULL所以要具体需求来决定对于notin和notexists的性能区别:notin只有当子查询中,select关键字后的字段有not null约束或者有这种暗示时用notin,另外如果主查询中表大,子查询中的表小但是记录多,则应当使用notin,并使用anti hash join.如果主查询表中记录少,子查询表中记录多,并有索引,可以使用notexists,另外notin最好也可以用/*+ HASH_AJ */或者外连接+is null

NOTIN在基于成本的应用中较好比如:

select .....

from rollup R

where notexists( 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 NOTIN( 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';

R

R

R

+

R

R

R

分享到:

2011-08-11 18:53

浏览 3577

分类:数据库

评论

mysql sql exists_数据库sql语句的exists总结相关推荐

  1. SQL 选择数据库 USE语句

    SQL 选择数据库 USE语句 当SQL Schema中有多个数据库时,在开始操作之前,需要选择一个执行所有操作的数据库. SQL USE语句用于选择SQL架构中的任何现有数据库. 句法 USE语句的 ...

  2. html连接数据库id号自动生成器,SQL Server数据库sql语句生成器(SqlDataToScript)的使用(sql server自增列(id)插入固定值)...

    SqlDataToScript是根据表数据进行生成 Insert Into语句,此工具还有一个好处是可以对自增列插入固定值,例如:自增的列id值为5,但是5这个行值已经删除,如果想存储Id自增列值为5 ...

  3. MYSQL批量插入数据库实现语句性能分析

    MYSQL批量插入数据库实现语句性能分析 假定我们的表结构如下 代码如下   CREATE TABLE example ( example_id INT NOT NULL, name VARCHAR( ...

  4. 检测java是否连接到SQL server数据库 + SQL server数据库内置账户sa无法登录

    检测java是否连接到SQL server数据库 + SQL server数据库内置账户sa无法登录 SQL 检测java是否连接到SQL server数据库 SQL server数据库内置账户SA登 ...

  5. 计算机导论sql试题,数据库SQL语句练习题

    一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四个表的结构分别如表1-1的表(一)~表( ...

  6. SQL Server 数据库SQL语句中CURSOR(游标)的使用

    本文主讲SQL Server数据库中 游标CURSOR 的使用,欢迎阅读~

  7. mysql lag over_数据库sql 使用 lag 和OVER 函数和 like 使用 小技巧

    1. sample 1: Lag()就是取当前顺序的上一行记录.结合over就是分组统计数据的. Lag()函数,就是去上N行的字段的数据. SQL> select * from x; A -- ...

  8. MySQL和SQL Server数据库基本语句总结(二)

    接着上面的总结,这一篇主要是MySQL剩下的内容(我用的不多,记下来,防止自己忘记) 1.关于触发器 解释   类似于C++中的事件触发,在一个事件发生后会执行里面的代码 (before /after ...

  9. SQL Server 数据库SQL语句

    创建Student表: create table Student( Sno char(7) not null primary key, Sname char(6) , Ssex char(2) , S ...

最新文章

  1. 泛化 实现 组合 聚合 关联 依赖
  2. C# 运算符的优先级和关联性
  3. Kubernetes中分布式存储Rook-Ceph的使用:一个ASP.NET Core MVC的案例
  4. java中的throw_Java中的throw和throws之间的区别
  5. Redis:Cannot assign requested address的解决办法
  6. (56)FPGA条件选择有优先级(case)
  7. 安装 pear、phpunit 测试用例步骤方法
  8. mysql不能删除外键吗,为什么mysql不允许删除外键?
  9. C语言平面几何19-三角形的重心和垂心
  10. AMD Opteron
  11. 书评与摘抄《白鹿原》
  12. 地表最强之Android微信语音/腾讯会议通话录音
  13. [Extjs6]浅谈Ext.data.Store的使用.
  14. 刘汝佳《算法竞赛入门经典(第二版)》习题(三)
  15. vue笔记(coderwhy)
  16. OpenCV 无法解析的外部符号 __imp_opj_image_destroy解决方案
  17. 开课吧大圣老师性能优化训练营笔记
  18. ph值图片_人体血液正常PH值图片
  19. 计算机辅助化工制图,计算机辅助化工制图与设计.pdf
  20. 遍历json 对象的属性并且动态添加属性

热门文章

  1. YARN组件详细介绍
  2. 那些年,我们解析过的前端异常
  3. 【编译原理笔记18】代码优化:活跃变量分析,可用表达式分析
  4. 【python】一道LeetCode搞懂递归算法!#131分割回文串 #以及刷LeetCode的一点点小心得 [数据结构与算法基础]
  5. 软件测试入门随笔——软件测试基础知识(一)
  6. JS让本地图片预览不再难-jquery插件
  7. zabbix------监控小技巧
  8. 十八、AR数据库的关联查询relations之单条数据查询
  9. django mysql windows_Django+MySQL配置:Windows+Centos
  10. 气门组的结构组成有哪些_挖机破碎钳子,液压粉碎钳都有哪些结构组成,你知道吗...