IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况
发布日期:2021-06-29 05:05:51
浏览次数:2
分类:技术文章
本文共 2214 字,大约阅读时间需要 7 分钟。
SQL里的EXISTS与in、 not exists与 not in 效率比较和使用
在 MSSQL 中,插入(insert)一条记录很简单,但是一些特殊应用,在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,本文介绍的就是这个问题的解决方案。
问题: 我创建了一个表来存放客户信息,我知道可以用 insert 语句插入信息到表中,但是怎么样才能保证不会插入重复的记录呢? 答案: 可以通过使用 EXISTS 条件句防止插入重复记录。 示例一:插入多条记录 假设有一个主键为 client_id 的 clients 表,可以使用下面的语句: Code: INSERT INTO clients (client_id, client_name, client_type) SELECT supplier_id, supplier_name, 'advertising' FROM suppliers WHERE not exists (select * from clients where clients.client_id = suppliers.supplier_id);
个人批注:not exists不存在,也就是说后面的括号中只要返回了数据那么这个条件就不存在了,可以理解为括号前的not
exists是一个左表达式 ,括号后的查询是一个右表达式,只有当右表达式返回的也是not exists(即后面的查询出来的结果是非空的)时,等式才成立。
示例一:插入单条记录 Code:
INSERT INTO clients (client_id, client_name, client_type) SELECT 10345, 'IBM', 'advertising' FROM dual WHERE not exists (select * from clients where clients.client_id = 10345);
使用 dual 做表名可以让你在 select 语句后面直接跟上要插入字段的值,即使这些值还不存在当前表中。
系统要求进行SQL优化,对效率比较低的SQL进行优化,使其运行效率更高,其中要求对SQL中的部分in/not in修改为exists/not exists
修改方法如下:
in的SQL语句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime
FROM tab_oa_pub WHERE is_check=1 and category_id in (select id from tab_oa_pub_cate where no='1') order by begintime desc修改为exists的SQL语句
SELECT id, category_id, htmlfile, title, convert(varchar(20),begintime,112) as pubtime FROM tab_oa_pub WHERE is_check=1 and exists (select id from tab_oa_pub_cate where tab_oa_pub.category_id=convert(int,no) and no='1') order by begintime desc分析一下exists真的就比in的效率高吗?
我们先讨论IN和EXISTS。
select * from t1 where x in ( select y from t2 ) 事实上可以理解为: select * from t1, ( select distinct y from t2 ) t2 where t1.x = t2.y; ——如果你有一定的SQL优化经验,从这句很自然的可以想到t2绝对不能是个大表,因为需要对t2进行全表的“唯一排序”,如果t2很大这个排序的性能是不可忍受的。但是t1可以很大,为什么呢?最通俗的理解就是因为t1.x=t2.y可以走索引。但这并不是一个很好的解释。试想,如果t1.x和t2.y都有索引,我们知道索引是种有序的结构,因此t1和t2之间最佳的方案是走merge join。另外,如果t2.y上有索引,对t2的排序性能也有很大提高。 select * from t1 where exists ( select null from t2 where y = x ) 可以理解为: for x in ( select * from t1 ) loop if ( exists ( select null from t2 where y = x.x ) then OUTPUT THE RECORD! end if end loop ——这个更容易理解,t1永远是个表扫描!因此t1绝对不能是个大表,而t2可以很大,因为y=x.x可以走t2.y的索引。 综合以上对IN/EXISTS的讨论,我们可以得出一个基本通用的结论:IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。我们要根据实际的情况做相应的优化,不能绝对的说谁的效率高谁的效率低,所有的事都是相对的
转载地址:https://blog.csdn.net/zhaokuner/article/details/9817127 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
感谢大佬
[***.8.128.20]2024年04月19日 13时32分12秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
2020年Security+备考经验分享
2019-04-29
工具集电子书等4G资料免费分享(IT 信安菜鸟入门必备)
2019-04-29
备考干货「三」CISM(国际注册信息安全经理)考过笔记
2019-04-29
大学生有哪些信息安全认证可以考?
2019-04-29
2020年Security+备考经验分享(二)
2019-04-29
ITIL4,全球IT行业抢手的资格认证之一
2019-04-29
CRISC备考重点知识解读
2019-04-29
推荐信息安全书籍27本(含电子书)
2019-04-29
攻防对抗蓝队必修课——文末有文档模板分享
2019-04-29
云计算领域的安全威胁如何应对?
2019-04-29
你了解三证合一的数据保护官(DPO)吗?
2019-04-29
小白入门网络安全,需要学习哪些内容?
2019-04-29
如何找回丢失的比特币
2019-04-29
日本交易所Zaif因黑客攻击损失近6000万美元
2019-04-29
以太坊智能合约如何运作?
2019-04-29
赛迪全球公链指数第5期名单:EOS、ETH排名不变 比特股首进前3
2019-04-29
能依靠0.21个比特币生存21天吗
2019-04-29
比特币核心发现网络漏洞CVE-2018-17144 社区敦促所有节点尽快升级补丁
2019-04-29
泰达币对比特币价格的影响不具有统计意义
2019-04-29