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返回很多⾏的话)。
- 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谓词表示:
或者是:。