转 exists  in

http://www.cnblogs.com/highriver/archive/2011/05/30/2063461.html

SQL中IN和EXISTS用法的区别

1.exist,not exist一般都是与子查询一起使用. In可以与子查询一起使用,也可以直接in (a,b.....)

2.exist会针对子查询的表使用索引. not exist会对主子查询都会使用索引. in与子查询一起使用的时候,只能针对主查询使用索引. not in则不会使用任何索引. 注意,一直以来认为exists比in效率高的说法是不准确的。

in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
如果查询的两个表大小相当,那么用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=A.cc)
效率高,用到了B表上cc列的索引。
相反的2:select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索引。
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大,用not exists都比not in要快。

3.exist与in都可以实现一个目的.二者都可以用来过滤数据.

示例:

复制代码
select count ( 1 ) from t1; -- 160W
select count ( 1 ) from t2; -- 90W


SELECT count ( 1 )
FROM t1 a
WHERE EXISTS ( SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid); -- 主大子小,不适合使用exist,因为exist只会利用子表t2的复合索引keyid+ideaid,而子表内容要小与主表,主表由于无法使用索引,查询效率低下.



select count ( 1 ) from t1 a where accountid in ( SELECT accountid
FROM t2 b
WHERE a.keyid = b.keyid AND a.ideaid = b.ideaid); -- 主大子小,适合用in,因为in只会使用主表t1里面的复合主键keyid-ideaid,在主表大于子表的情况下,会很好的利用主表的索引.


-- 后二条sql的执行结果都是一样的.说明exist与in在用法上可以达到一个目的,不同的地方是
--
1.性能的考虑此时就按子表大主表小用exist,子表小主表大用in的原则就可以.
--
2.写法的不同, exist的where条件是: "...... where exist (..... where a.id=b.id)"
--
in的where条件是: " ...... where id in ( select id .... where a.id=b.id)"
复制代码
4. exist的原理:

exists做为where 条件时,是先对where 前的主查询询进行查询,然后用主查询的结果一个一个的代入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是一对多的关系 A.ID --> B.AID

SELECT ID , NAME FROM A WHERE EXISTS (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

5. in 与 =的区别
select name from student where name in ('zhang','wang','li','zhao');

select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。

in的字段也可以与其它字段建复合索引.

比如

T1包含下面key, accountd,groupid.

复制代码
SELECT *
FROM T1 a
WHERE a.groupid = 2001
AND a.accountid = 1001
AND a. key IN ( ' abc ' , ' def ' , ' ala ' );

-- 上面的sql可以将accountid,key建成复合索引.
复制代码

请分析下面代码:<#import "/decorators/includes/macros.ftl" as m> <#assign ww = JspTaglibs["/WEB-INF/webwork.tld"] /> <#include "/template/includes/actionerrors.ftl"> <#assign useStepNo=false> <#if requestForm.stepForms?exists> <#list requestForm.stepForms as stepForm> <#if stepForm.stepNo?exists> <#assign useStepNo=true> </#if> </#list> </#if> <script> document.onkeydown = function() { if(event.keyCode==116) { event.keyCode=0; event.returnValue = false; } if ((window.event.altKey)&&(window.event.keyCode==115)){ //屏蔽Alt+F4 event.keyCode=0; event.returnValue=false; alert("Please do not exit like this again. This case maybe have some problem cause of the action.Please check it.\r\n 请下次不要再这样退出。由于你的这个动作,这个单子可能已经产生了错误,请检查。"); return false; } if ((event.ctrlKey)&&(event.keyCode==87)){ //屏蔽 Ctrl+n event.keyCode=0; event.returnValue=false; return false; } } //document.oncontextmenu = function() {event.returnValue = false;} function continueRuncard(){ var date = new Date(); var minute=date.getMinutes(); if(parseInt(minute)>=0 && parseInt(minute)<=5) { alert("整点系统同步中.\n请稍后再试!"); return false; } var compareResultComment=document.getElementById("compareResultComment"); if (compareResultComment!=null){ confineStringLength(compareResultComment,500); if(compareResultComment.value==""){ return false; } } var form = document.forms['']; form.action="continueRuncard.action"; form.submit(); } function cancelRuncard(){ var date = new Date(); var minute=date.getMinutes(); if(parseInt(minute)>=0 && parseInt(minute)<=5) { alert("整点系统同步中.\n请稍后再试!"); return false; } var form = document.forms['submitRequestFormForm']; form.action="cancelRuncard.action"; form.submit(); } function compareWithMes(){ <#if Rework> alert("Because RunCard's category is rework. \r\n System will not execute this function!"); return false; </#if> var form = document.forms['submitRequestFormForm']; if(!confirm("Do you want to create the comparison with MES document?\n你是否需要E-RC与MES做对比?\n\n确定 = E-RC对比MES(此动作可能需要花费几分钟时间,请耐心等待)\n\n取消 = E-RC不比对MES")){ return false; } form.action="eRuncardRule.action"; form.submit(); } function submitRunCard(){ var compareResultComment=document.getElementById("compareResultComment"); if (compareResultComment!=null){ confineStringLength(compareResultComment,500); if(compareResultComment.value==""){ return false; } } var date = new Date(); var minute=date.getMinutes(); if(parseInt(minute)>=0 && parseInt(minute)<=5) { alert("整点系统同步中.\n请稍后再试!"); return false; } disableButton(); var f=document.submitRequestFormForm; f.action = "submitRequestForm.action"; var xmlHttp = XmlHttp.create(); var async = false; xmlHttp.open("GET", "checkStepNoExistInFecp.action?lotId=${requestForm.lotId?if_exists}&holdStepNo=${requestForm.holdStepNo?if_exists}", async); xmlHttp.send(null); if(xmlHttp.responseText != null && xmlHttp.responseText == '<success/>'){ if (!confirm("你确认是否需要在这步做STR/MSTR and Link STR/MSTR \nNumber? If yes, 请确认E-runcard condition exactly \n match with FECP/STR, MSTR system\n\n确定 = 确认 Link STR/MSTR Number, submit E-runcard \n\n取消 = 修改 E-runcard")){ f.action = "viewUpdateRequestForm.action"; //f.submit(); } f.submit(); }else if(xmlHttp.responseXML != null && xmlHttp.responseXML.getElementsByTagName("success").length > 0){ if (!confirm("你确认是否需要在这步做STR/MSTR and Link STR/MSTR \nNumber? If yes, 请确认E-runcard condition exactly \n match with FECP/STR, MSTR system\n\n确定 = 确认 Link STR/MSTR Number, submit E-runcard \n\n取消 = 修改 E-runcard")){ f.action = "viewUpdateRequestForm.action"; //f.submit(); } f.submit(); }else{ f.submit(); } } </script> <@ww.form name="'submitRequestFormForm'" namespace="'/user'" validate="'true'" method="'post'" theme="'simple'"> <@ww.hidden name="'requestFormId'" value="${requestForm.id}"/> <@ww.token name="submitToken"/> <div class="app"> <h3>View e-Runcard Request Form</h3> <table border="0" cellspacing="1" cellpadding="8" width="100%"> <tr class="b"> <td>RunCard No.:</td> <td>${requestForm.caseNo?if_exists}</td> <td>Status:</td> <td><font color="red">${requestForm.status?if_exists}</font></td> </tr> <tr class="b"> <td>Applicant:</td> <td><@m.directoryLink requestForm.applicant?if_exists/> </td> <td>Organization:</td> <td>${requestForm.applicantOrg?if_exists}</td> </tr> <tr class="b"> <td>Submit Date:</td> <td>${requestForm.submitDate?if_exists}</td> <td>Effective Date:</td> <td>${requestForm.effectiveDate?if_exists}</td> </tr> <#include "viewIncludeLotInfo.ftl"/> <#include "viewIncludeSignInfo.ftl"/> <#include "viewIncludeErcHeaderInfo.ftl"/> <#include "viewIncludeErcCompleteInfo.ftl"/> <#switch requestForm.formType> <#case "Auto Reposition Step"> <#break> <#default> <table border="0" cellspacing="1" cellpadding="8" width="100%"> <tr> <th colspan="4">RunCard Steps Information</th> </tr> <#assign showWGAction = true > <#include "stepForm/includeStepForm.ftl"/> </table> </#switch> </table> <hr/> <#if requestForm.match?default("")=="N"> <table border="0" cellspacing="1" cellpadding="8" width="100%"> <tr class="b"> <td>Compare Result Comment <BR>请输入原因(Only 500 characters)</td> <td><@ww.textarea name="'requestForm.compareResultComment'" id="compareResultComment" cols="80" rows="5" theme="'simple'"/></td> </tr> </table> </#if> <table width="100%"> <tr> <td class="center"> <#if requestForm.formType="Normal"> <input type="button" onclick="compareWithMes()" value="Compare"/>&nbsp;&nbsp;&nbsp;&nbsp; </#if> <#if requestForm.haveQtime?exists> <#if requestForm.haveQtime=="Y"> <#if requestForm.formType!="Scan Defect"> <#if requestForm.formType="Normal" && useStepNo && requestForm.match=="No Comparison" && !Rework> <input type="button" class="btn" value="Continue Runcard" onclick="alert('please compare runcard first.');"/>&nbsp;&nbsp;&nbsp;&nbsp; <#else> <input type="button" class="btn" value="Continue Runcard" onclick="continueRuncard()"/>&nbsp;&nbsp;&nbsp;&nbsp; </#if> </#if> <input type="button" class="btn" value="Cancel Runcard" onclick="cancelRuncard()"/>&nbsp;&nbsp;&nbsp;&nbsp; </#if> <#else> <#if requestForm.formType="Normal" && useStepNo && requestForm.match=="No Comparison" && !Rework> <input type="button" class="btn" value="Submit" onclick="alert('please compare runcard first.');"/>&nbsp;&nbsp;&nbsp;&nbsp; <#else> <input type="button" class="btn" value="Submit" onclick="submitRunCard()"/>&nbsp;&nbsp;&nbsp;&nbsp; </#if> <input type="button" class="btn" value="Back" onclick="document.location.href='${req.contextPath}/user/viewUpdateRequestForm.action?requestFormId=${requestForm.id}'"/> </#if> </td> </tr> </table> <div> </@ww.form>
最新发布
09-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值