数据库中IN 和EXISTS有什么区别?

数据库中IN 和EXISTS有什么区别?,第1张

没有什么区别,两者都是包含的意思,但是esists的效率比in要高。建议别用in,影响效率 ,如果只有两三个条件,就用or代替 ,如果值 比较多,就用exists.例如 select * from table where ( name = '1' or name ='2') 别写成name in ('1','2')如果数据量比较大select * from table where name exists (select name from table2)

1、适用表的类型不同。

in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而外面的表结果集大的情况。

exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面的表结果集小而子查询结果集大的情况。

2、子查询关联不同。

exists一般都是关联子查询。对于关联子查询,必须先执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。

in则一般都是非关联子查询,非关联子查询则必须先完成内层查询之后,外层查询才能介入。

3、执行次数不同。

IN 语句:只执行一次,确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。

EXISTS语句:执行次数根据表的长度而定。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有没有和内表的数据一样的。匹配上就将结果放入结果集中。

SQL语句语言特点:

1、SQL风格统一

SQL可以独立完成数据库生命周期中的全部活动,包括定义关系模式、录人数据、建立数据库、査询、更新、维护、数据库重构、数据库安全性控制等一系列 *** 作,这就为数据库应用系统开发提供了良好的环境,在数据库投入运行后,还可根据需要随时逐步修改模式,且不影响数据库的运行,从而使系统具有良好的可扩充性。

2、高度非过程化

非关系数据模型的数据 *** 纵语言是面向过程的语言,用其完成用户请求时,必须指定存取路径。而用SQL进行数据 *** 作,用户只需提出“做什么”,而不必指明“怎么做”,因此用户无须了解存取路径,存取路径的选择以及SQL语句的 *** 作过程由系统自动完成。这不但大大减轻了用户负担,而且有利于提高数据独立性。

1.exist,notexist一般都是与子查询一起使用.In可以与子查询一起使用,也可以直接in(a,b.....)\x0d\x0a\x0d\x0a2.exist会针对子查询的表使用索引.notexist会对主子查询都会使用索引.in与子查询一起使用的时候,只能针对主查询使用索引.notin则不会使用任何索引.注意,一直以来认为exists比in效率高的说法是不准确的。\x0d\x0ain是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。\x0d\x0a如果查询的两个表大小相当,那么用in和exists差别不大。\x0d\x0a如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:\x0d\x0a例如:表A(小表),表B(大表)1:select*fromAwhereccin(selectccfromB)\x0d\x0a效率低,用到了A表上cc列的索引;select*fromAwhereexists(selectccfromBwherecc=A.cc)\x0d\x0a效率高,用到了B表上cc列的索引。\x0d\x0a相反的2:select*fromBwhereccin(selectccfromA)\x0d\x0a效率高,用到了B表上cc列的索引;select*fromBwhereexists(selectccfromAwherecc=B.cc)\x0d\x0a效率低,用到了A表上cc列的索引。\x0d\x0anotin和notexists如果查询语句使用了notin那么内外表都进行全表扫描,没有用到索引;而notextsts的子查询依然能用到表上的索引。所以无论那个表大,用notexists都比notin要快。\x0d\x0a3.exist与in都可以实现一个目的.二者都可以用来过滤数据.\x0d\x0a示例:\x0d\x0a\x0d\x0aselectcount(1)fromt1--160W\x0d\x0aselectcount(1)fromt2--90W\x0d\x0a\x0d\x0aSELECTcount(1)\x0d\x0aFROMt1a\x0d\x0aWHEREEXISTS(SELECTaccountid\x0d\x0aFROMt2b\x0d\x0aWHEREa.keyid=b.keyidANDa.ideaid=b.ideaid)--主大子小,不适合使用exist,因为exist只会利用子表t2的复合索引keyid+ideaid,而子表内容要小与主表,主表由于无法使用索引,查询效率低下.\x0d\x0a\x0d\x0aselectcount(1)fromt1awhereaccountidin(SELECTaccountid\x0d\x0aFROMt2b\x0d\x0aWHEREa.keyid=b.keyidANDa.ideaid=b.ideaid)--主大子小,适合用in,因为in只会使用主表t1里面的复合主键keyid-ideaid,在主表大于子表的情况下,会很好的利用主表的索引.\x0d\x0a\x0d\x0a--后二条sql的执行结果都是一样的.说明exist与in在用法上可以达到一个目的,不同的地方是\x0d\x0a--1.性能的考虑此时就按子表大主表小用exist,子表小主表大用in的原则就可以.\x0d\x0a--2.写法的不同,exist的where条件是:"......whereexist(.....wherea.id=b.id)"\x0d\x0a--in的where条件是:"......whereidin(selectid....wherea.id=b.id)"\x0d\x0a\x0d\x0a4.exist的原理:\x0d\x0aexists做为where条件时,是先对where前的主查询询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出\x0d\x0a比如\x0d\x0a如下:\x0d\x0a表A\x0d\x0aIDNAME\x0d\x0a1A1\x0d\x0a2A2\x0d\x0a3A3\x0d\x0a\x0d\x0a表B\x0d\x0aIDAIDNAME\x0d\x0a11B1\x0d\x0a22B2\x0d\x0a32B3\x0d\x0a\x0d\x0a表A和表B是一对多的关系A.ID-->B.AID\x0d\x0a\x0d\x0aSELECTID,NAMEFROMAWHEREEXISTS(SELECT*FROMBWHEREA.ID=B.AID)\x0d\x0a执行结果为\x0d\x0a1A1\x0d\x0a2A2\x0d\x0a原因可以按照如下分析\x0d\x0aSELECTID,NAMEFROMAWHEREEXISTS(SELECT*FROMBWHEREB.AID=1)\x0d\x0a-->SELECT*FROMBWHEREB.AID=1有值返回真所以有数据\x0d\x0a\x0d\x0aSELECTID,NAMEFROMAWHEREEXISTS(SELECT*FROMBWHEREB.AID=2)\x0d\x0a-->SELECT*FROMBWHEREB.AID=2有值返回真所以有数据\x0d\x0a\x0d\x0aSELECTID,NAMEFROMAWHEREEXISTS(SELECT*FROMBWHEREB.AID=3)\x0d\x0a-->SELECT*FROMBWHEREB.AID=3无值返回真所以没有数据\x0d\x0a\x0d\x0aNOTEXISTS就是反过来\x0d\x0aSELECTID,NAMEFROMAWHERENOTEXIST(SELECT*FROMBWHEREA.ID=B.AID)\x0d\x0a执行结果为\x0d\x0a3A3\x0d\x0a5.in与=的区别\x0d\x0aselectnamefromstudentwherenamein('zhang','wang','li','zhao')\x0d\x0a与\x0d\x0aselectnamefromstudentwherename='zhang'orname='li'orname='wang'orname='zhao'\x0d\x0a的结果是相同的。\x0d\x0ain的字段也可以与其它字段建复合索引.\x0d\x0a比如\x0d\x0aT1包含下面key,accountd,groupid.\x0d\x0a\x0d\x0aSELECT*\x0d\x0aFROMT1a\x0d\x0aWHEREa.groupid=2001\x0d\x0aANDa.accountid=1001\x0d\x0aANDa.keyIN('abc','def','ala')\x0d\x0a\x0d\x0a--上面的sql可以将accountid,key建成复合索引.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9985662.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存