WHY?

IN 和 NOT IN 是比较常用的关键字,为什么要尽量避免呢?

1、效率低

可以参看我之前遇到的一个例子([小问题笔记(九)] SQL语句Not IN 效率低,用 NOT EXISTS试试

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)。

转发自:http://www.cnblogs.com/hydor/p/5391556.html

sql优化 in 和 not in 语句的更多相关文章

  1. SQL优化清单

    SQL优化清单 1.from 语句中包含多个表的情况下,把记录数少的表放在前面 2.where 语句中包含多个条件时,将刷选多的条件放前面 3.避免使用select * ,因为这样会去查询所有列的数据 ...

  2. ORACLE常用SQL优化hint语句

    在SQL语句优化过程中,我们经常会用到hint,现总结一下在SQL优化过程中常见Oracle HINT的用法: 1. /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量, ...

  3. SQL优化的四个方面,缓存,表结构,索引,SQL语句

    一,缓存 数据库属于 IO 密集型的应用程序,其主要职责就是数据的管理及存储工作.而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个IO是在毫秒级别,二者相差3个数量级.所 ...

  4. 智能SQL优化工具--SQL Optimizer for SQL Server(帮助提升数据库应用程序性能,最大程度地自动优化你的SQL语句 )

    SQL Optimizer for SQL Server 帮助提升数据库应用程序性能,最大程度地自动优化你的SQL语句 SQL Optimizer for SQL Server 让 SQL Serve ...

  5. SQL优化之语句优化

    昨天与大家分享了SQL优化中的索引优化,今天给大家聊一下,在开发过程中高质量的代码也是会带来优化的 网上关于SQL优化的教程很多,但是比较杂乱.整理了一下,写出来跟大家分享一下,其中有错误和不足的地方 ...

  6. MySQL5.6 怎样优化慢查询的SQL语句 -- SQL优化

    上篇:MySQL5.6 怎样优化慢查询的SQL语句 -- 慢日志介绍 在实际的日志分析中,通常慢日志的log数量不少,同一时候同样的查询被记录的条数也会非常多.这里就须要怎样从慢日志查询中找到最有问题 ...

  7. MySql(五)SQL优化-优化SQL语句的一般步骤

    MySql(五)SQL优化-优化SQL语句的一般步骤 一.优化SQL语句的一般步骤 1.1 通过show status命令了解各种SQL的执行频率 1.2 定位执行效率较低的SQL语句 1.3 通过e ...

  8. SQL优化案例—— RowNumber分页

    将业务语句翻译成SQL语句不仅是一门技术,还是一门艺术. 下面拿我们程序开发工程师最常用的ROW_NUMBER()分页作为一个典型案例来说明. 先来看看我们最常见的分页的样子: WITH CTE AS ...

  9. sql 优化

    1.选择最有效率的表名顺序(只在基于规则的优化器中有效): oracle的解析器按照从右到左的顺序处理 from 子句中的表名,from子句中写在最后的表(基础表driving table)将被最先处 ...

随机推荐

  1. Linux文件系统与目录结构

    在Linux系统中,目录被组织成一个:单根倒置树结构,文件系统从根目录开始,用/来表示.文件名称区分大小写( 大小写敏感还需要看具体的文件系统格式 ),以.开头的为隐藏文件,路径用/来进行分割(win ...

  2. HTTP协议中request报文请求方法和状态响应码

    一个HTTP请求报文由4部分组成: 请求行(request line) 请求头部(header) 空行 请求数据 下图给出了请求报文的一般格式: 请求行中包括了请求方法,常见的请求方法有: GET:从 ...

  3. redis数据库的安装配置

    redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcached类似,但很大程度补偿了memcached的不足,它支持存储的value类型相对更多,包括strin ...

  4. dede后台添加优酷等视频iframe链接时被替换成了图片

     添加文章时 添加优酷视频 :<iframe height=498 width=510 src='http://player.youku.com/embed/XNDAzNTAzODE4OA==' ...

  5. linux 特殊命令(一)

    1.ifconfig 网卡配置:ifconfig  [网络设备] [参数] 1) up 启动指定网络设备/网卡. 2) down 关闭指定网络设备/网卡.该参数可以有效地阻止通过指定接口的IP信息流, ...

  6. 第4章 HDFS操作

    目录 4.1 命令行操作 4.2 Java API操作 4.2.1 创建Java工程 4.2.2 读取数据 4.2.3 创建目录 4.2.4 创建文件 4.2.5 删除文件 4.2.6 遍历文件和目录 ...

  7. js for 循环中有异步函数时,回调函数总是最后一步的值。

    原因:for循环执行时不会等待异步函数执行. 解决方法: 1.改为递归函数(暂时不会). 2.构建一个自执行函数传参(匿名函数) 参考::https://www.cnblogs.com/csuwuji ...

  8. maston总结

    Substitution Tags(替换标签) % ; # this is embedded Perl You have <% $cd_count %> CDs. Escaping sub ...

  9. swoole创建websocket服务器

    目录 1 安装准备 1.1 安装swoole前必须保证系统已经安装了下列软件 1.2 下载并解压 1.3 编译安装成功后,修改php.ini 2 构建Swoole基本实例 2.1 tcp服务器实例 2 ...

  10. Asp.net Core发布到CentOS7

    第一步.安装CentOS 官网https://www.centos.org/下载CentOS,下载地址https://www.centos.org/download/,我选的“DVD ISO”,然后虚 ...