SQL中exist与in的区别
SQL优化-数据库SQL优化——使用EXIST代替IN
SQL优化-数据库SQL优化——使⽤EXIST代替IN1,查询进⾏优化,应尽量避免全表扫描对查询进⾏优化,应尽量避免全表扫描,⾸先应考虑在 where 及 order by 涉及的列上建⽴索引. 尝试下⾯的技巧以避免优化器错选了表扫描:· 使⽤ANALYZE TABLEtbl_name为扫描的表更新关键字分布。
· 对扫描的表使⽤FORCEINDEX告知,相对于使⽤给定的索引表扫描将⾮常耗时。
SELECT * FROM t1, t2 FORCE INDEX (index_for_column) WHERE t1.col_name=t2.col_name;· ⽤–max-seeks-for-key=1000选项启动mysqld或使⽤SET max_seeks_for_key=1000告知优化器假设关键字扫描不会超过1,000次关键字搜索。
1). 应尽量避免在 where ⼦句中对字段进⾏ null 值判断否则将导致引擎放弃使⽤索引⽽进⾏全表扫描,如:select id from t where num is nullNULL对于⼤多数数据库都需要特殊处理,MySQL也不例外,它需要更多的代码,更多的检查和特殊的索引逻辑,有些开发⼈员完全没有意识到,创建表时NULL是默认值,但⼤多数时候应该使⽤NOT NULL,或者使⽤⼀个特殊的值,如0,-1作为默不能⽤null作索引,任何包含null值的列都将不会被包含在索引中。
即使索引有多列这样的情况下,只要这些列中有⼀列含有null,该列就会从索引中排除。
也就是说如果某列存在空值,即使对该列建索引也不会提⾼性能。
任何在where⼦句中使⽤此例可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=02). 应尽量避免在 where ⼦句中使⽤!=或<>操作符否则将引擎放弃使⽤索引⽽进⾏全表扫描。
SQL查询中in和exists的区别分析
SQL查询中in和exists的区别分析select * from A where id in (select id from B);select * from A where exists (select 1 from B where A.id=B.id);对于以上两种情况,in是在内存⾥遍历⽐较,⽽exists需要查询数据库,所以当B表数据量较⼤时,exists效率优于in。
1、select * from A where id in (select id from B);它的查询过程类似于以下过程:复制代码代码如下:List resultSet={};Array A=(select * from A);Array B=(select id from B);for(int i=0;i<A.length;i++) {for(int j=0;j<B.length;j++) {if(A[i].id==B[j].id) {resultSet.add(A[i]);break;}}}return resultSet;如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差。
再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数⼤⼤减少,效率⼤⼤提升。
2、select * from A where exists (select 1 from B where A.id=B.id);它的查询过程类似于以下过程:复制代码代码如下:List resultSet={};Array A=(select * from A);for(int i=0;i<A.length;i++) {if(exists(A[i].id) { //执⾏select 1 from B where B.id=A.id是否有记录返回resultSet.add(A[i]);}}return resultSet;当B表⽐A表数据⼤时适合使⽤exists(),因为它没有那么多遍历操作,只需要再执⾏⼀次查询就⾏。
SQL中IN与EXISTS关键字
SQL中IN与EXISTS关键字 偶遇这样⼀个场景,使⽤IN关键字进⾏检索数据所消耗的时间是使⽤EXISTS关键字进⾏检索数据所消耗的时间的接近30倍。
⼀看差距这么⼤,查阅了⼀本SQL数据,其中也没有介绍多少,不过我们可以从其定义中可以领悟到⼀些差异。
(1)IN关键字:该操作符IN⽤于把⼀个值与⼀个指定列表进⾏⽐较,当被⽐较的值⾄少与列表中的⼀个值相匹配时,它会返回TRUE。
(2)EXISTS关键字:该操作符EXISTS⽤于搜索指定表⾥是否存在满⾜特定条件的记录。
根据这两个关键字作⽤的描述,可知:若是IN⼦句或者EXISTS⼦句都是采⽤SELECT语法检索出来的结果列表进⾏匹配的话,那么在IN⼦句中还要将被⽐较值与结果列表做进⼀步的循环⽐较,当IN中的被⽐较值能够匹配到结果列表中某个值,那么IN⼦句就会返回TRUE,否则的话就会返回FALSE;⽽在EXISTS⼦句中,若SELECT语句检索的结果值不为空,那么EXISTS⼦句直接将该结果集返回,若是检索的结果值为空的,那么EXISTS⼦句就返回空,也就是说EXISTS⼦句返回的就是SELECT语句返回的结果集,不需要再次做⽐较判断了。
-- INSELECT column1FROM table_nameWHERE some_col IN (SELECT column1 FROM table_name WHERE other_col >'xx');-- EXISTSSELECT column1FROM table_nameWHERE EXISTS (SELECT column1 FROM table_name WHERE other_col >'xx'); 上述代码⽰例只是⼀个象征性的对⽐说明,在同⼀个表中进⾏不同条件的多次检索,使⽤IN的⽅式:先根据条件检索出数据,然后some_col与结果列表进⾏循环⽐较;使⽤EXISTS的⽅式:先根据条件检索出数据,然后将该结果集直接返回,作为最终的数据结果了。
对比分析MySQL语句中的IN和Exists
对⽐分析MySQL语句中的IN和Exists背景介绍最近在写SQL语句时,对选择IN 还是Exists 犹豫不决,于是把两种⽅法的SQL都写出来对⽐⼀下执⾏效率,发现IN的查询效率⽐Exists⾼了很多,于是想当然的认为IN的效率⽐Exists好,但本着寻根究底的原则,我想知道这个结论是否适⽤所有场景,以及为什么会出现这个结果。
⽹上查了⼀下相关资料,⼤体可以归纳为:外部表⼩,内部表⼤时,适⽤Exists;外部表⼤,内部表⼩时,适⽤IN。
那我就困惑了,因为我的SQL语句⾥⾯,外表只有1W级别的数据,内表有30W级别的数据,按⽹上的说法应该是Exists的效率会⽐IN⾼的,但我的结果刚好相反!!“没有调查就没有发⾔权”!于是我开始研究IN 和Exists的实际执⾏过程,从实践的⾓度出发,在根本上去寻找原因,于是有了这篇博⽂分享。
实验数据我的实验数据包括两张表:t_author表和 t_poetry表。
对应表的数据量:t_author表,13355条记录;t_poetry表,289917条记录。
对应的表结构如下:CREATE TABLE t_poetry (id bigint(20) NOT NULL AUTO_INCREMENT,poetry_id bigint(20) NOT NULL COMMENT '诗词id',poetry_name varchar(200) NOT NULL COMMENT '诗词名称',<font color=red> author_id bigint(20) NOT NULL COMMENT '作者id'</font>PRIMARY KEY (id),UNIQUE KEY pid_idx (poetry_id) USING BTREE,KEY aid_idx (author_id) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=291270 DEFAULT CHARSET=utf8mb4CREATE TABLE t_author (id int(15) NOT NULL AUTO_INCREMENT,author_id bigint(20) NOT NULL,</font>author_name varchar(32) NOT NULL,dynasty varchar(16) NOT NULL,poetry_num int(8) NOT NULL DEFAULT '0'PRIMARY KEY (id),<font color=red>UNIQUE KEY authorid_idx (author_id) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=13339 DEFAULT CHARSET=utf8mb4执⾏计划分析 IN 执⾏过程sql⽰例:select * from tabA where tabA.x in (select x from tabB where y>0 );其执⾏计划:(1)执⾏tabB表的⼦查询,得到结果集B,可以使⽤到tabB表的索引y;(2)执⾏tabA表的查询,查询条件是tabA.x在结果集B⾥⾯,可以使⽤到tabA表的索引x。
in和extexs
in和exists的区别与SQL执行效率in和exists的区别与SQL执行效率最近很多论坛又开始讨论in和exists的区别与SQL执行效率的问题,本文特整理一些in和exists的区别与SQL执行效率分析SQL中in可以分为三类:1、形如select * from t1 where f1 in ('a','b'),应该和以下两种比较效率select * from t1 where f1='a' or f1='b'或者select * from t1 where f1 ='a' union all select * from t1 f1='b'你可能指的不是这一类,这里不做讨论。
2、形如select * from t1 where f1 in (select f1 from t2 where t2.fx='x'),其中子查询的where里的条件不受外层查询的影响,这类查询一般情况下,自动优化会转成exist语句,也就是效率和exist一样。
3、形如select * from t1 where f1 in (select f1 from t2 where t2.fx=t1.fx),其中子查询的where里的条件受外层查询的影响,这类查询的效率要看相关条件涉及的字段的索引情况和数据量多少,一般认为效率不如exists。
除了第一类in语句都是可以转化成exists 语句的SQL,一般编程习惯应该是用exi sts而不用in,而很少去考虑in和exists的执行效率.in和exists的SQL执行效率分析A,B两个表,(1)当只显示一个表的数据如A,关系条件只一个如ID时,使用IN更快:select * from A where id in (select id from B)(2)当只显示一个表的数据如A,关系条件不只一个如ID,col1时,使用IN就不方便了,可以使用EXISTS:select * from Awhere exists (select 1 from B where id = A.id and col1 = A.col1)(3)当只显示两个表的数据时,使用IN,EXISTS都不合适,要使用连接:select * from A left join B on id = A.id所以使用何种方式,要根据要求来定。
mysql中=与in区别_浅析mysql中exists与in的区别,空判断
mysql中=与in区别_浅析mysql中exists与in的区别,空判断1、exists的使⽤exists对外表⽤loop逐条查询,每次查询都会查看exists的条件语句,当exists⾥的条件语句能够返回记录⾏时(⽆论记录⾏是的多少,只要能返回),条件就为真,返回当前loop到的这条记录;反之如果exists⾥的条件语句不能返回记录⾏,则当前loop到的这条记录被丢弃,exists的条件就像⼀个bool条件,当能返回结果集则为true,不能返回结果集则为 false。
如下:select * from user where exists (select 1);对user表的记录逐条取出,由于⼦条件中的select 1永远能返回记录⾏,那么user表的所有记录都将被加⼊结果集,所以与 select * from user;是⼀样的。
如下:select * from user where exists (select * from user where userId = 0);可以知道对user表进⾏loop时,检查条件语句(select * from user where userId = 0),由于userId永远不为0,所以条件语句永远返回空集,条件永远为false,那么user表的所有记录都将被丢弃。
not exists与exists相反,也就是当exists条件有结果集返回时,loop到的记录将被丢弃,否则将loop到的记录加⼊结果集。
总的来说,如果A表有n条记录,那么exists查询就是将这n条记录逐条取出,然后判断n遍exists条件。
2、in 的使⽤in查询相当于多个or条件的叠加,这个⽐较好理解,⽐如下⾯的查询:select * from user where userId in (1, 2, 3);等效于select * from user where userId = 1 or userId = 2 or userId = 3;not in 与 in相反,如下select * from user where userId not in (1, 2, 3);等效于select * from user where userId != 1 and userId != 2 and userId != 3;总的来说,in查询就是先将⼦查询条件的记录全都查出来,假设结果集为B,共有m条记录,然后再将⼦查询条件的结果集分解成m个,再进⾏m次查询。
详解sql中exists和in的语法与区别
详解sql中exists和in的语法与区别exists和in的区别很⼩,⼏乎可以等价,但是sql优化中往往会注重效率问题,今天咱们就来说说exists和in的区别。
exists语法:select … from table where exists (⼦查询)将主查询的结果,放到⼦查询结果中进⾏校验,如⼦查询有数据,则校验成功,那么符合校验,保留数据。
create table teacher(tid int(3),tname varchar(20),tcid int(3));insert into teacher values(1,'tz',1);insert into teacher values(2,'tw',2);insert into teacher values(3,'tl',3);例如:select tname from teacher exists(select * from teacher);此sql语句等价于select tname from teacher(主查询数据存在于⼦查询,则查询成功(校验成功))此sql返回为空,因为⼦查询并不存在这样的数据。
in语法:select … from table where 字段 in (⼦查询)select ..from table where tid in (1,3,5) ;select * from A where id in (select id from B);区别:如果主查询的数据集⼤,则使⽤in;如果⼦查询的数据集⼤,则使⽤exists;例如:select tname from teacher where exists (select * from teacher);这⾥很明显,⼦查询查询所有,数据集⼤,使⽤exists,效率⾼。
select * from teacher where tname in (select tname from teacher where tid = 3);这⾥很明显,主查询数据集⼤,使⽤in,效率⾼。
mysql中EXISTS和IN的使用方法比较
mysql中EXISTS和IN的使⽤⽅法⽐较1、使⽤⽅式:(1)EXISTS⽤法select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b where a.projectId = b.id)上⾯这条SQL的意思就是:以ucsc_project_batch为主表查询batchName与projectId字段,其中projectId字段存在于ucsc_project表中。
EXISTS 会对外表ucsc_project_batch进⾏循环查询匹配,它不在乎后⾯的内表⼦查询的返回值是什么,只在乎有没有存在返回值,存在返回值,则条件为真,该条数据匹配成功,加⼊查询结果集中;如果没有返回值,条件为假,丢弃该条数据。
例如我们这⾥改变⼀下⼦查询的查询返回字段,并不影响外查询的查询结果:select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select panyId, from ucsc_project b where a.projectId = b.id)(2)IN⽤法select a.batchName,a.projectId from ucsc_project_batch a where a.projectId in (select b.id from ucsc_project b)上⾯这条SQL的查询结果与刚才的EXISTS的结果⼀样,查询的意思也⼀样。
2、注意点:(1)EXISTS写法需要注意⼦查询中的条件语句⼀般需要带上外查询的表做关联,不然⼦查询的条件可能会⼀直为真,或者⼀直为假,外查询的表进⾏循环匹配的时候,要么全部都查询出来,要么⼀条也没有。
select a.batchName,a.projectId from ucsc_project_batch a where EXISTS (select b.id from ucsc_project b)⽐如上述这种写法,由于ucsc_project 表存在值,⼦查询的条件⼀直为真,ucsc_project_batch 每条数据进⾏循环匹配的时候,都能匹配成功,查询出来的结果就成为了ucsc_project_batch整张表数据。
mysql的in和exists用法
MySQL中的IN和EXISTS都是用于在子查询中测试条件的操作符,但它们的用法和性能特点有所不同。
1.IN操作符:IN用于在子查询中返回一个值的列表,并在主查询中测试该值是否在列表中。
语法如下:sqlSELECT column1, column2, ...FROM table1WHERE column_name IN (value1, value2, ...);例如,假设我们有一个名为orders的表,其中包含订单信息,我们想要查询订单状态为"shipped"的订单:sqlSELECT *FROM ordersWHERE status IN ('shipped', 'delivered');这将返回状态为"shipped"或"delivered"的所有订单。
2.EXISTS操作符:EXISTS用于测试子查询是否返回任何结果。
如果子查询返回至少一行结果,则EXISTS返回真(TRUE),否则返回假(FALSE)。
语法如下:sqlSELECT column1, column2, ...FROM table1WHERE EXISTS (subquery);例如,假设我们想要查询至少有一个订单的客户:sqlSELECT customer_nameFROM customersWHERE EXISTS (SELECT 1 FROM orders WHERE orders.customer_id = customers.customer_id);这将返回至少有一个订单的客户列表。
总结:IN用于测试值是否在给定的列表中,而EXISTS用于测试子查询是否返回任何结果。
选择使用IN还是EXISTS取决于具体的查询需求和数据结构。
sql中的exists
sql中的exists刚开始⼯作的开发,很容易过度的使⽤in、not in。
其实,在有些时候可以⽤exists、not exists来代替in和not in,实现查询性能的提升。
exists操作符时候会和in操作符产⽣混淆。
因为他们都是⽤于检查某个属性是否包含在某个集合中。
但是相同点也仅限于此。
exists的真正⽬的是检查⼦查询是否⾄少包含⼀条记录。
例如,下⾯的查询会返回⾏1和2:WITH numbers (nr) AS (SELECT 1 AS nr UNION ALLSELECT 2 AS nr UNION ALLSELECT 3 AS nr), letters (letter, nr) AS (SELECT 'A' AS letter, 1 AS nr UNION ALLSELECT 'B' AS letter, 2 AS nr)SELECT * FROM numbers n WHERE EXISTS (SELECT nr FROM letters WHERE nr= n.nr);当然,你也可以改写成in:WITH numbers (nr) AS (SELECT 1 AS nr UNION ALLSELECT 2 AS nr UNION ALLSELECT 3 AS nr), letters (letter, nr) AS (SELECT 'A' AS letter, 1 AS nr UNION ALLSELECT 'B' AS letter, 2 AS nr)SELECT * FROM numbers n WHERE n.nr IN (SELECT nr FROM letters);这两种写法,都可以返回相同的记录。
区别是exists会更快,因为在得到第⼀条满⾜条件的记录之后就会停⽌,⽽in会查询所有的记录(如果in返回很多⾏的话)。
sql中exists用法
sql中exists用法exists是SQL中的一种检查函数,用于判断一条SQL子句是否存在结果集,在SQL中exists的使用可以极大地提高查询效率。
exists函数相比"in"函数有很大的优势,即exists在找到结果情况下,会立刻返回True,而"in"函数会把所有结果查出来才进行判断。
如需要确定是否有顾客名叫“张三”的,一般会使用in函数:select * from customers where name in("张三");此SQL会把customers表中所有的name值为“张三”的记录拿出来,然后再处理,比较耗时的情况下,可以使用exists:select * from customers where exists(select 1 from customers where name = "张三");exists把结果集直接返回,无需在customers表上多余的查询,大大提高查询效率。
这也是当今大数据场景下exists函数受到青睐。
除了简单用法之外,exists函数还可以与其它结合起来使用,比如查找满足条件X和Y其中一个的记录:select * from customers where exists(select 1 from customers where name = "张三") or exists(select 1 from customers where name = ”Ping";由于存在exists函数,当今的查询任务变得超级快捷。
exists函数不仅用于极大地提升SQL查询效率,也可以启发我们在生活中不断改善效率,把更多时间留出来完成更有意义的事情。
oracle中exist与in的区别
在Oracle SQL中取数据时有时要用到in 和exists 那么他们有什么区别呢?1 性能上的比较比如Select * from T1 where x in ( select y from T2 )执行的过程相当于:select *from t1, ( select distinct y from t2 ) t2where t1.x = t2.y;相对的select * from t1 where exists ( select null from t2 where y = x )执行的过程相当于:for x in ( select * from t1 )loopif ( exists ( select null from t2 where y = x.x )thenOUTPUT THE RECORDend ifend loop表 T1 不可避免的要被完全扫描一遍分别适用在什么情况?以子查询 ( select y from T2 )为考虑方向如果子查询的结果集很大需要消耗很多时间,但是T1比较小执行( select null from t2 where y = x.x )非常快,那么exists就比较适合用在这里相对应得子查询的结果集比较小的时候就应该使用in.2 含义上的比较在标准的scott/tiger用户下执行SQL> select count(*) from emp where empno not in ( select mgr from emp );COUNT(*)----------SQL> select count(*) from emp T12 where not exists ( select null from emp T2 where t2.mgr =t1.empno ); -- 这里子查询中取出null并没有什么特殊作用,只是表示取什么都一样。
COUNT(*)----------8结果明显不同,问题就出在MGR=null的那条数据上。
数据库in和exists的用法
数据库in和exists的用法数据库in和exists的用法的用法如下:SELECTDISTINCTMD001FROMBOMMDWHEREMD001NOTIN(SELECTMC001F ROMBOMMC)NOTEXISTS,exists的用法跟in不一样,一般都需要和子表进行关联,而且关联时,需要用索引,这样就可以加快速度selectDISTINCTMD001fromBOMMDWHERENOTEXISTS(SELECTMC001FR OMBOMMCwhereBOMMC.MC001=BOMMD.MD001)exists是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真,否则返回假。
notexists则相反。
exists做为where条件时,是先对where前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出。
in和existsin是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
一直以来认为exists比in 效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:例如:表A(小表),表B(大表)1:select*fromAwhereccin(selectccfromB)效率低,用到了A表上cc列的索引;select*fromAwhereexists(selectccfromBwherecc=)效率高,用到了B表上cc列的索引。
相反的2:select*fromBwhereccin(selectccfromA)效率高,用到了B表上cc列的索引;select*fromBwhereexists(selectccfromAwherecc=)效率低,用到了A表上cc列的索引。
SQL中IN和EXISTS用法的区别
SET NOCOUNT ON,SET NOCOUNT OFF当SET NOCOUNT 为ON 时,不返回计数(表示受Transact-SQL 语句影响的行数)。
当SET NOCOUNT 为OFF 时,返回计数。
如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。
SQL中IN和EXISTS用法的区别NOT INSELECT DISTINCT MD001 FROM BOMMD WHERE MD001 NOT IN (SELECT MC001 FROM BOMMC)NOT EXISTS,exists的用法跟in不一样,一般都需要和子表进行关联,而且关联时,需要用索引,这样就可以加快速度select DISTINCT MD001 from BOMMD WHERE NOT EXISTS (SELECT MC001 FROM BOMMC where BOMMC.MC001 = BOMMD.MD001)exists是用来判断是否存在的,当exists(查询)中的查询存在结果时则返回真,否则返回假。
not exists则相反。
exists做为where 条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出。
in和existsin是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:例如:表A(小表),表B(大表)1:select*from A where cc in (select cc from B)效率低,用到了A表上cc列的索引;select*from A where exists(select cc from B where cc=)效率高,用到了B表上cc列的索引。
exists和in的用法
"exists"和"in"在英语中常常用于不同的语境中,表达不同的含义。
以下是关于这两个词的一些基本用法和注意事项:**exists**1. **存在性**:这个词主要用于表达某个实体或概念在某个集合或范围内是存在的。
例如:“Does anyone exist in this class?”(这个班级里有人存在吗?)这里的“exist”是动词,表示“存在”。
2. **存在状态**:当我们谈论某个物体或情况的存在状态时,我们可能会使用“exists”。
例如:“My car exists in my garage.”(我的车在车库里。
)在这个句子中,“exists”表示的是一种存在状态。
**in**1. **在……里面**:这个用法主要用于表示位置或范围。
例如:“The cat is in the kitchen.”(猫在厨房里。
)在这个句子中,“in”表示的是空间位置。
2. **用某种语言或方式**:当我们在描述某种行为或情况时,我们可能会使用“in”。
例如:“She speaks French very well, in a clear and confident way.”(她法语说得非常好,用清晰而自信的方式。
)在这个句子中,“in”表示方式。
3. **在某个时间或时期**:当我们谈论某个事件或活动发生的时间或时期时,我们可能会使用“in”。
例如:“The party started in the early evening.”(晚会开始于傍晚早些时候。
)**用法建议**在使用这两个词时,建议根据语境选择合适的词。
一般来说,“exists”更常用于描述事物的存在状态,而“in”则更常用于描述空间位置、方式或时间。
同时,注意不要混淆这两个词的用法,以免产生误解。
另外,在某些情况下,你可能需要查阅相关词典或语法书籍以获取更准确和详细的解释。
这些资源通常会提供更多关于这两个词的用法、含义和例句的信息,帮助你更好地理解和使用它们。
sql中exists,notexists的用法
sql中exists,notexists的⽤法exists : 强调的是是否返回结果集,不要求知道返回什么, ⽐如:select name from student where sex = 'm' and mark exists(select 1 from grade where ...) ,只要exists引导的⼦句有结果集返回,那么exists这个条件就算成⽴了,⼤家注意返回的字段始终为1,如果改成“select 2 from grade where ...”,那么返回的字段就是2,这个数字没有意义。
所以exists⼦句不在乎返回什么,⽽是在乎是不是有结果集返回。
⽽ exists 与 in 最⼤的区别在于 in引导的⼦句只能返回⼀个字段,⽐如:select name from student where sex = 'm' and mark in (select 1,2,3 from grade where ...),in⼦句返回了三个字段,这是不正确的,exists⼦句是允许的,但in只允许有⼀个字段返回,在1,2,3中随便去了两个字段即可。
⽽not exists 和not in 分别是exists 和 in 的对⽴⾯。
exists (sql 返回结果集为真) not exists (sql 不返回结果集为真)下⾯详细描述not exists的过程:如下:表AID NAME 1 A12 A23 A3表BID AID NAME1 1 B12 2 B2 3 2 B3表A和表B是1对多的关系 A.ID => B.AIDSELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHEREA.ID=B.AID)执⾏结果为1 A12 A2原因可以按照如下分析SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)--->SELECT * FROM B WHERE B.AID=1有值返回真所以有数据SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)--->SELECT * FROM B WHERE B.AID=2有值返回真所以有数据SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)--->SELECT * FROM B WHERE B.AID=3⽆值返回真所以没有数据NOT EXISTS 就是反过来SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)执⾏结果为3A3===========================================================================EXISTS = IN,意思相同不过语法上有点点区别,好像使⽤IN效率要差点,应该是不会执⾏索引的原因SELECTID,NAME FROM A WHERE ID IN (SELECT AID FROM B)NOT EXISTS = NOT IN ,意思相同不过语法上有点点区别SELECT ID,NAME FROM A WHERE ID NOT IN (SELECT AID FROM B)有时候我们会遇到要选出某⼀列不重复,某⼀列作为选择条件,其他列正常输出的情况.如下⾯的表table:Id Name Class Count Date1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果想要得到下⾯的结果:(Id唯⼀,Date选最近的⼀次)1 ⾹蕉⽔果 15 2011-7-32 青菜蔬菜 19 2011-7-2正确的SQL语句是:SELECT Id, Name, Class, Count, DateFROM table tWHERE (NOT EXISTS(SELECT Id, Name, Class, Count, Date FROM tableWHERE Id = t.Id AND Date > t.Date))如果⽤distinct,得不到这个结果, 因为distinct是作⽤与所有列的SELECT DISTINCT Id, Name, Class, Count, Date FROM table结果是表table的所有不同列都显⽰出来,如下所⽰:1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果⽤Group by也得不到需要的结果,因为Group by 要和聚合函数共同使⽤,所以对于Name,Class和Count列要么使⽤Group by,要么使⽤聚合函数. 如果写成SELECT Id, Name, Class, Count, MAX(Date)FROM tableGROUP BY Id, Name, Class, Count得到的结果是1 苹果⽔果 10 2011-7-11 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 ⽩菜蔬菜 12 2011-7-12 青菜蔬菜 19 2011-7-2如果写成SELECT Id, MAX(Name), MAX(Class), MAX(Count), MAX(Date)FROM tableGROUP BY Id得到的结果是:1 ⾹蕉⽔果 20 2011-7-32 青菜蔬菜 19 2011-7-2如果⽤in有时候也得不到结果,(有的时候可以得到,如果Date都不相同(没有重复数据),或者是下⾯得到的Max(Date)只有⼀个值)SELECT DISTINCT Id, Name, Class, Count, Date FROM tableWHERE (Date IN(SELECT MAX(Date)FROM tableGROUP BY Id))得到的结果是:(因为MAX(Date)有两个值2011-7-2,2011-7-3)1 桔⼦⽔果 20 2011-7-21 ⾹蕉⽔果 15 2011-7-32 青菜蔬菜 19 2011-7-2注意in只允许有⼀个字段返回有⼀种⽅法可以实现:SELECT Id, Name, Class, COUNT, DateFROM table1 tWHERE (Date = (SELECT MAX(Date) FROM table1 WHERE Id = t .Id))⽐如在Northwind数据库中有⼀个查询为SELECT c.CustomerId,CompanyName FROM Customers cWHERE EXISTS(SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID) 这⾥⾯的EXISTS是如何运作呢?⼦查询返回的是OrderId字段,可是外⾯的查询要找的是CustomerID和CompanyName字段,这两个字段肯定不在OrderID⾥⾯啊,这是如何匹配的呢? EXISTS⽤于检查⼦查询是否⾄少会返回⼀⾏数据,该⼦查询实际上并不返回任何数据,⽽是返回值True或FalseEXISTS 指定⼀个⼦查询,检测⾏的存在。
数据库sql语句的exists和in的区别
数据库sql语句的exists和in的区别性能变化的关键:#1 执⾏的先后顺序谁是驱动表,谁先执⾏查询,谁后执⾏查询#2 执⾏过程exists的优点是:只要存在就返回了,这样的话很有可能不需要扫描整个表。
in需要扫描完整个表,并返回结果。
所以,在字表⽐较⼩的情况下,扫描全表和部分表基本没有差别;但在⼤表情况下,exists就会有优势。
看这两个语句:--⼦查询会执⾏完全关联,并返回所有符合条件的city_idselect * 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的性能区别:如果⼦查询得出的结果集记录较少,主查询中的表较⼤且⼜有索引时应该⽤in,反之如果外层的主查询记录较少,⼦查询中的表⼤,⼜有索引时使⽤exists。
其实我们区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执⾏⼦查询,所以我们会以驱动表的快速返回为⽬标,那么就会考虑到索引及结果集的关系了另外IN时不对NULL进⾏处理。
注意:NOT EXISTS与 NOT IN不能完全互相替换,看具体的需求。
如果选择的列可以为空,则不能被替换。
对于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在基于成本的应⽤中较好。
sqlserverin和exists的区别
sqlserverin和exists的区别如图,现在有两个数据集,左边表⽰#tempTable1,右边表⽰#tempTable2。
现在有以下问题:1.求两个集的交集?2.求tempTable1中不属于集#tempTable2的集?先创建两张临时表:create table #tempTable1(argument1 nvarchar(50),argument2 varchar(20),argument3 datetime,argument4 int);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher001','130********',GETDATE()-1,1);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher002','23218757',GETDATE()-2,2);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher003','13018757',GETDATE()-3,3);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher004','13023257',GETDATE()-4,4);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher005','13023218',GETDATE()-5,5);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher006','13023218',GETDATE()-6,6);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher007','13023218',GETDATE()-7,7);insert into #tempTable1(argument1,argument2,argument3,argument4)values('preacher008','13023218',GETDATE()-8,8);create table #tempTable2(argument1 nvarchar(50),argument2 varchar(20),argument3 datetime,argument4 int);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher001','130********',GETDATE()-1,1);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher0010','23218757',GETDATE()-10,10);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher003','13018757',GETDATE()-3,3);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher004','13023257',GETDATE()-4,4);insert into #tempTable2(argument1,argument2,argument3,argument4)values('preacher009','13023218',GETDATE()-9,9);⽐如,我现在以#tempTable1和#tempTable2的argument1作为参照1.求两集的交集:1)in ⽅式select * from #tempTable2 where argument1 in(select argument1 from #tempTable1)2)exists ⽅式select * from #tempTable2 t2 where exists(select * from #tempTable1 t1 where t1.argument1=t2.argument1)2.求tempTable1中不属于集#tempTable2的集1)in ⽅式select * from #tempTable1 where argument1 not in(select argument1 from #tempTable2)2)exists ⽅式select * from #tempTable1 t1 where not exists(select * from #tempTable2 t2 where t1.argument1=t2.argument1)3)exists对应数据的⾏索引例如现在有两张表tbl_customer,tbl_phone,其中⼀个客户对应⼀个或多个电话信息,在维护电话号码时,往往会显⽰例如客户姓名、客户性别、修改⼈、修改时间等等点,查看选中的客户电话详细记录时可以查看该客户名义下的所有电话号码信息;因为是维护的客户电话号码,所以这⾥的修改⼈和修改时间应该针对的是当前客户对应的所有电话号码的最新修改时间,那么在提取这些数据时,可以使⽤ max() 和 exists获取这⼀个特别数据。
mysql中in和exits的区别
mysql中in和exits的区别表展⽰ 查询中涉及到的两个表,⼀个user和⼀个order表,具体表的内容如下: user表: order表:in ⼀、确定给定的值是否与⼦查询或列表中的值相匹配。
in在查询的时候,⾸先查询⼦查询的表,然后将内表和外表做⼀个笛卡尔积,然后按照条件进⾏筛选。
所以相对内表⽐较⼩的时候,in的速度较快。
具体sql语句如下:1 SELECT2 *3 FROM4 `user`5 WHERE6 `user`.id IN (7 SELECT8 `order`.user_id9 FROM10 `order`11 ) 这条语句很简单,通过⼦查询查到的user_id 的数据,去匹配user表中的id然后得到结果。
该语句执⾏结果如下: 它的执⾏流程是什么样⼦的呢?让我们⼀起来看⼀下。
⾸先,在数据库内部,查询⼦查询,执⾏如下代码:SELECT`order`.user_idFROM`order` 执⾏完毕后,得到结果如下: 此时,将查询到的结果和原有的user表做⼀个笛卡尔积,结果如下: 此时,再根据我们的user.id IN er_id的条件,将结果进⾏筛选(既⽐较id列和user_id 列的值是否相等,将不相等的删除)。
最后,得到两条符合条件的数据。
⼆、select * from A where id in(select id from B)以上查询使⽤了in语句,in()只执⾏⼀次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加⼊结果集中,直到遍历完A表的所有记录. 它的查询过程类似于以下过程List resultSet=[]; Array A=(select * from A); Array B=(select id from B);for(int i=0;i<A.length;i++) { for(int j=0;j<B.length;j++) { if(A[i].id==B[j].id) { resultSet.add(A[i]); break; } } } return resultSet;可以看出,当B表数据较⼤时不适合使⽤in(),因为它会B表数据全部遍历⼀次. 如:A表有10000条记录,B表有1000000条记录,那么最多有可能遍历10000*1000000次,效率很差. 再如:A表有10000条记录,B表有100条记录,那么最多有可能遍历10000*100次,遍历次数⼤⼤减少,效率⼤⼤提升.结论:in()适合B表⽐A表数据⼩的情况exists ⼀、指定⼀个⼦查询,检测⾏的存在。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
SQL中exist与in的区别
in 是一个集合运算符.
a in {a,c,d,s,d....} P105例子
这个运算中,前面是一个元素,后面是一个集合,集合中的元素类型是和前面的元素一样的.
而exists是一个存在判断,如果后面的查询中有结果,则exists为真,否则为假.
in 运算用在语句中,它后面带的select 一定是选一个字段,而不是select *.
比如说你要判断某班是否存在一个名为"小明"的学生,你可以用in 运算:
"小明" in (select sname from student)
这样(select sname from student) 返回的是一个全班姓名的集合,in用于判断"小明"是否为此集合中的一个数据;
同时,你也可以用exists语句:
exists (select * from student where sname="小明")
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
这句相当于
select * from 表A where id in (select id from 表B)
对于表A的每一条数据,都执行select * from 表B where 表B.id=表A.id的存在性判断,如果表B中存在表A当前行相同的id,则exists为真,该行显示,否则不显示
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
表A
ID NAME
1 A1
2 A2
3 A3
表B
ID AID NAME
1 1 B1
2 2 B2
3 2 B3
表A和表B是1对多的关系 A.ID => B.AID
SELECT ID,NAME FROM A WHERE EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
1 A1
2 A2
原因可以按照如下分析
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=1)
--->SELECT * FROM B WHERE B.AID=1有值返回真所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=2)
--->SELECT * FROM B WHERE B.AID=2有值返回真所以有数据
SELECT ID,NAME FROM A WHERE EXISTS (SELECT * FROM B WHERE B.AID=3)
--->SELECT * FROM B WHERE B.AID=3无值返回真所以没有数据
NOT EXISTS 就是反过来
SELECT ID,NAME FROM A WHERE NOT EXIST (SELECT * FROM B WHERE A.ID=B.AID)
执行结果为
3 A3
例子查询选修了全部课程的学生姓名。
(∀ x)P⇔⌝ (∃ x (P)) 查询学生x,不存在课程y,学生没有选修
例查询选修了全部课程的学生姓名。
用x表示课程,p(x)表示学生学习了课程x,则(∀ x)p(x)表示对所有课程学生都学习了。
1.依次取出一个学生,对任何一个课程,查看该学生是否选修了。
如果未选修,返回该课
程。
2.如果选修了,则查看下一个课程。
3.最终,如果返回的所有课程为空的话说明该学生选修了所有的课程。
此时输出该学生的
信息。
例查询至少选修了学生95002选修的全部课程的学生号码。
解题思路:
用逻辑蕴函表达:查询学号为x的学生,对所有的课程y,只要95002学生选修了课程y,则x也选修了y。
形式化表示:
用P表示谓词“学生95002选修了课程y”
用q表示谓词“学生x选修了课程y”
则上述查询为: (∀y) p→q
等价变换:
(∀y) p→q⇔⌝(∃ y (⌝(p→q)) ⇔⌝(∃ y (⌝(⌝p∨q) ⇔⌝(∃ y (p∧q)
变换后语义:不存在这样的课程y,学生95002选修了y,而学生x没有选。
用NOT EXISTS谓词表示:
或者是:。