SQL优化 - 避免使用 IN 和 NOT IN
WHY?
- IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?
1、效率低
- 项目中遇到这么个情况:
- t1表 和 t2表 都是150w条数据,600M的样子,都不算大。
- 但是这样一句查询
select * from t1 where phone not in (select phone from t2) - 直接就把我跑傻了。。。十几分钟,检查了一下 phone在两个表都建了索引,字段类型也是一样的。原来not in 是不能命中索引的。。。。
- 改成 NOT EXISTS 之后查询 20s ,效率真的差好多。
- select * from t1
- where not EXISTS (select phone from t2 where t1.phone =t2.phone)
2、容易出现问题,或查询结果有误 (不能更严重的缺点)
- 以 IN 为例。建两个表:test1 和 test2
- create table test1 (id1 int)
- create table test2 (id2 int)
- insert into test1 (id1) values (1),(2),(3)
- insert into test2 (id2) values (1),(2)
- 我想要查询,在test2中存在的 test1中的id 。使用IN的一般写法是:
- select id1 from test1
- where id1 in (select id2 from test2)
- 结果是:
OK 木有问题!
- 但是如果我一时手滑,写成了:
- select id1 from test1
- where id1 in (select id1 from test2)
- 不小心把id2写成id1了 ,会怎么样呢?
- 结果是:
EXCUSE ME! 为什么不报错?
- 单独查询 select id1 from test2 是一定会报错: 消息 207,级别 16,状态 1,第 11 行 列名 'id1' 无效。
- 然而使用了IN的子查询就是这么敷衍,直接查出 1 2 3
- 这仅仅是容易出错的情况,自己不写错还没啥事儿,下面来看一下 NOT IN 直接查出错误结果的情况:
- 给test2插入一个空值:
insert into test2 (id2) values (NULL)
- 我想要查询,在test2中不存在的 test1中的id 。
- select id1 from test1
- where id1 not in (select id2 from test2)
- 结果是:
空白! 显然这个结果不是我们想要的。我们想要3。为什么会这样呢?
- 原因是:NULL不等于任何非空的值啊!如果id2只有1和2, 那么3<>1 且 3<>2 所以3输出了,但是 id2包含空值,那么 3也不等于NULL 所以它不会输出。
(跑题一句:建表的时候最好不要允许含空值,否则问题多多。)
HOW?
1、用 EXISTS 或 NOT EXISTS 代替
- select * from test1
- where EXISTS (select * from test2 where id2 = id1 )
- select * FROM test1
- where NOT EXISTS (select * from test2 where id2 = id1 )
2、用JOIN 代替
- select id1 from test1
- INNER JOIN test2 ON id2 = id1
- select id1 from test1
- LEFT JOIN test2 ON id2 = id1
- where id2 IS NULL
妥妥的没有问题了!
- PS:那我们死活都不能用 IN 和 NOT IN 了么?并没有,一位大神曾经说过,如果是确定且有限的集合时,可以使用。如 IN (0,1,2)。
SQL优化 - 避免使用 IN 和 NOT IN的更多相关文章
- SQL优化案例—— RowNumber分页
将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...
- sql 优化
1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表driving table)将被最先处 ...
- SQL 优化总结
SQL 优化总结 (一)SQL Server 关键的内置表.视图 1. sysobjects SELECT name as '函数名称',xtype as XType FROM s ...
- (转)SQL 优化原则
一.问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...
- sql优化阶段性总结以及反思
Sql优化思路阶段性心得: 这段时间的优化做了好几个案例,其实有很多的类似点,都是好几张大表的相互连接,然后执行长达好几个小时,甚至都跑不出来. 自己差不多的思路就是Parallel full tab ...
- mysql sql优化实例
mysql sql优化实例 优化前: pt-query-degist分析结果: # Query 3: 0.00 QPS, 0.00x concurrency, ID 0xDC6E62FA021C85B ...
- SQL优化技巧
我们开发的大部分软件,其基本业务流程都是:采集数据→将数据存储到数据库中→根据业务需求查询相应数据→对数据进行处理→传给前台展示.对整个流程进行分析,可以发现软件大部分的操作时间消耗都花在了数据库相关 ...
- ORACLE常用SQL优化hint语句
在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...
- SQL优化有偿服务
本人目前经营MySQL数据库的SQL优化服务,100块钱一条.具体操作模式 其中第一条,可以通过在微信朋友圈转发链接中的信息(http://www.yougemysqldba.com/discuz/v ...
- 【MySQL】SQL优化系列之 in与range 查询
首先我们来说下in()这种方式的查询 在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的. ...
随机推荐
- 一个简单的基于多进程实现并发的Socket程序
在单进程的socket的程序的基础上,实现多进程并发效果的思路具体是:在server端开启“链接循环”,每建立一次链接就生成一个Process对象进行server-client的互动,而client端 ...
- 知识点:java 注解 @SuppressWarnings
前言: 简介:java.lang.SuppressWarnings是J2SE5.0中标准的Annotation之一.可以标注在类.字段.方法.参数.构造方法,以及局部变量上.作用:告诉编译器忽略指定的 ...
- tf.nn.embedding_lookup
tf.nn.embedding_lookup(params, ids, partition_strategy=’mod’, name=None, validate_indices=True, max_ ...
- SAS DATA ENCODING 解决odbc乱码问题
首先获取编码格式: %PUT %SYSFUNC(getOption(ENCODING)); libname findoout ODBC datasrc=SurveyReport user=shendu ...
- 理解HDFS高可用性架构
在Hadoop1.x版本的时候,Namenode存在着单点失效的问题.如果namenode失效了,那么所有的基于HDFS的客户端——包括MapReduce作业均无法读,写或列文件,因为namenode ...
- Android重打包+重新签名工具Apktool Box
可实现apk反编译+重新打包+重新签名,界面如下 : 部分引用自开源代码:http://github.com/Bu4275/AutoAPKTool
- Android CoordinatorLayout实现多列表切换并和头布局联动;
注意:不是双列表联动,是多列表和头布局联动: 大概就是和饿了么店铺首页类似的布局框架吧,头布局显示时,列表RecyclerView或ScrollView和头布局一起滚动,头布局完全隐藏后列表再去滚动, ...
- redis管道技术
1.redis管道pipeline解决的问题: 由于redis通信是通过tcp协议基础,并且是堵塞的处理方式,在第一个请求没有执行并返回前,无法处理第二个请求.所以事件浪费在了网络传输和堵塞请求中. ...
- c# 测试运行时间毫秒级
, , , , , , )).Ticks) / ; /*代码*/ , , , , , , )).Ticks) / ; MessageBox.Show((currentMillis1 - current ...
- 【Selenium-WebDriver自学】Selenium-IDE测试创建(三)
==================================================================================================== ...