SQL Server-聚焦NOT EXISTS AND NOT IN性能分析(十五)
前言
上一节我们分析了INNER JOIN和IN,对于不同场景其性能是不一样的,本节我们接着分析NOT EXISTS和NOT IN,简短的内容,深入的理解,Always to review the basics。
初步探讨NOT EXISTS和NOT IN
NOT EXISTS和NOT IN有很大的不同,尤其是对NULL的处理,为何这样说,当子查询中有NULL时,此时NOT IN不会返回任何行,下面我们来看下简单的示例。
USE TSQL2012
GO WITH table1 AS
(
SELECT AS value
UNION ALL
SELECT NULL AS nullcol1
),
table2 AS
(
SELECT AS value
UNION ALL
SELECT NULL AS nullcol2
)
首先我们来通过NOT EXISTS来进行查询
SELECT * FROM table1 AS a
WHERE NOT EXISTS(SELECT * FROM table2 AS b WHERE a.value = b.value)

接下来我们再来进行NOT IN查询
SELECT * FROM table1 AS a
WHERE value NOT IN(SELECT * FROM table2)

为何会出现不一样的结果呢,我们来分析下EXISTS和IN,EXISTS使用的是两值谓词逻辑,也就说说EXISTS总是返回TRUE或者FALSE,绝对不会返回UNKNOWN,而IN使用的三值谓词逻辑即返回的是TRUE或者FALSE或者UNKNOWN。当我们进行NOT EXISTS查询时,此时用1和NULL两行数据,此时1与table2中的值进行等值比较,此时没有相同的返回FALSE,接着NOT EXISTS则返回TRUE,所以此时返回1,同理返回NULL,当利用上述NOT IN进行查询时,我们可以将上述进行如下等价
SELECT * FROM table1 AS a
WHERE value NOT IN(SELECT * FROM table2)
等价于
WHERE (
value != (SELECT value FROM table2 WHERE value = )
AND
value != (SELECT value FROM table2 WHERE value = NULL)
)
当value = 1时,此时则有TRUE AND UNKNOWN结果还是UNKNOWN,同理当value = NULL时也是返回UNKNOWN,所以最终结果都未匹配上没有任何数据返回。
进一步探讨NOT EXISTS和NOT IN
接下来我们来进行NOT EXISTS和NOT IN的性能分析,接下来我们通过三种情况来进行分析。
(1)未建立索引情况比较NOT EXISTS和NOT IN
我们还是利用上一节的BigTable和SmallerTable来进行测试。
USE TSQL2012
GO SELECT ID, SomeColumn FROM BigTable
WHERE SomeColumn NOT IN (SELECT LookupColumn FROM SmallerTable) SELECT ID, SomeColumn FROM BigTable
WHERE NOT EXISTS (SELECT LookupColumn FROM SmallerTable WHERE SmallerTable.LookupColumn = BigTable.SomeColumn)

此时发现NOT EXISTS和NOT IN开销一致,解下来我们创建索引看看。
(2)创建索引比较NOT EXISTS和NOT IN
CREATE INDEX idx_BigTable_SomeColumn ON BigTable (SomeColumn)
CREATE INDEX idx_SmallerTable_LookupColumn ON SmallerTable (LookupColumn)
继续进行上述查询

创建了索引结果还是一致和上一节我们讨论的INNER JOIN和IN的情况有点不太一样,即使是创建唯一非聚集索引二者性能开销还是一致。到这里我们是不是可以下结论说二者性能一致呢,我们继续往下看,不知道大家发现了没有我们在上一节开始时对查询列的约束是不为空的,那要是为空结果又会是怎样的呢,我们看看。
(3)将查询列修改为可空
我们将SomeTable表和SmallerTable表中的SomeCloumn和LookupColumn修改为可空
USE TSQL2012
GO ALTER TABLE BigTable
ALTER COLUMN SomeColumn UNIQUEIDENTIFIER NULL ALTER TABLE SmallerTable
ALTER COLUMN LookupColumn UNIQUEIDENTIFIER NULL

查询计划显示结果大大出乎我们意料,为什么将列修改为可空的,此时NOT IN的性能开销接近是NOT EXISTS的33倍,猜测的话数据量越大这个差距应该是越来越明显。不知道为何如此,反正查询计划是如此,欺骗不了我们。在SQL Server 2012基础教程后续中无意中看到这样一句话:对EXISTS来说它会过滤掉NULL值。是不是当列定义为NULL时,IN不会过滤掉NULL,而EXISTS即使定义为NULL也会被自然过滤呢,不得而知。通过上述我们明确知道,有时候将列定义为空会减少我们的不必要的判断,但是在NOT EXISTS和NOT IN比较中,此时通过定义为NULL将会得到巨大的差异,至此,我们可以得出如下结论。
NOT EXISTS和NOT IN性能分析结论:当将查询列定义为NULL时,NOT EXISTS比NOT IN性能要好很多,当定义为非NULL时此时二者查询开销一样。当然如没有特殊情况,还是建议将查询列定义为非NULL,这样既可以保证查询性能,也可以保证在使用过程中NOT IN的安全性,减少不必要的性能开销。
总结
本节我们详细探讨了NOT EXISTS和NOT IN的性能情况,下一节我们开始探讨EXIST和IN的性能分析,简短的内容,深入的理解,我们下节再会。
SQL Server-聚焦NOT EXISTS AND NOT IN性能分析(十五)的更多相关文章
- SQL Server中修改“用户自定义表类型”问题的分析与方法
前言 SQL Server开发过程中,为了传入数据集类型的变量(比如接受C#中的DataTable类型变量),需要定义"用户自定义表类型",通过"用户自定义表类型&quo ...
- SQL SERVER 2012 执行计划走嵌套循环导致性能问题的案例
开发人员遇到一个及其诡异的的SQL性能问题,这段完整SQL语句如下所示: declare @UserId INT declare @PSANo VAR ...
- [翻译]——SQL Server使用链接服务器的5个性能杀手
前言: 本文是对博客http://www.dbnewsfeed.com/2012/09/08/5-performance-killers-when-working-with-linked-server ...
- 在SQL Server 2016里使用查询存储进行性能调优
作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题. 我就多次听到,以前的SQL Server的性能问题都还好且在正常范围内,但现在 ...
- 智能SQL优化工具--SQL Optimizer for SQL Server(帮助提升数据库应用程序性能,最大程度地自动优化你的SQL语句 )
SQL Optimizer for SQL Server 帮助提升数据库应用程序性能,最大程度地自动优化你的SQL语句 SQL Optimizer for SQL Server 让 SQL Serve ...
- SQL Server 手把手教你使用profile进行性能监控
200 ? "200px" : this.width)!important;} --> 介绍 经常会有人问profile工具该怎么使用?有没有方法获取性能差的sql的问题.自 ...
- SQL Server事务、隔离级别详解(二十九)
前言 事务一直以来是我最薄弱的环节,也是我打算重新学习SQL Server的出发点,关于SQL Server中事务将分为几节来进行阐述,Always to review the basics. 事务简 ...
- SQL Server 磁盘请求超时的833错误原因分析以及解决
本文出处:http://www.cnblogs.com/wy123/p/6984885.html 最近遇到一个SQL Server服务器响应极度缓慢,并且出现客户端请求报错的情况,在数据库中的erro ...
- SQL Server手把手教你使用profile进行性能监控
介绍 经常会有人问profile工具该怎么使用?有没有方法获取性能差的sql的问题.自从转mysql我自己也差不多2年没有使用profile,忽然profile变得有点生疏不得不重新熟悉一下.这篇文章 ...
随机推荐
- CMS模板应用调研问卷
截止目前,已经有数十家网站与我们合作,进行了MIP化改造,在搜索结果页也能看到"闪电标"的出现.除了改造方面的问题,MIP项目组被问到最多的就是:我用了wordpress,我用了织 ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- html与html5
HTML 是一种在 Web 上使用的通用标记语言.HTML 允许你格式化文本,添加图片,创建链接.输入表单.框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示.HTML 的关键是标签,其作用是 ...
- IIC驱动移植在linux3.14.78上的实现和在linux2.6.29上实现对比(deep dive)
首先说明下为什么写这篇文章,网上有许多博客也是介绍I2C驱动在linux上移植的实现,但是笔者认为他们相当一部分没有分清所写的驱动时的驱动模型,是基于device tree, 还是基于传统的Platf ...
- 用神奇的currentColor制作简洁的颜色动画效果
先上一个兼容性总结图:老版本ie可以直接用复杂方法了,套用某表情包的话: 2016年了,做前端你还考虑兼容IE6?你这简直是自暴自弃! 好了,知道了兼容性,我们可以放心的使用了. 在CSS3中扩展了 ...
- 阿里云学生优惠Windows Server 2012 R2安装IIS,ftp等组件,绑定服务器域名,域名解析到服务器,域名备案,以及安装期间错误的解决方案
前言: 这几天终于还是按耐不住买了一个月阿里云的学生优惠.只要是学生,在学信网上注册过,并且支付宝实名认证,就可以用9块9的价格买阿里云的云服务ECS.确实是相当的优惠. 我买的是Windows S ...
- SharePoint 2013管理中心里【管理服务器上的服务】不见了
打开管理中心,准备配置Managed Metadata Service,发现"管理服务器上的服务"不见了 那我自己拼url直接访问:http://xxxx/_admin/Serve ...
- 深入理解 Android 之 View 的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- thinkphp-无限分类下根据任意部门获取顶级部门ID
根据所得到的部门编号获取顶级部门ID: 参数 - department_id 表格组织架构: tab_departments department_id parent_id name 1 1 顶级 2 ...
- ASP.NET Aries 4.0 开源发布:已完成基础功能优化重写
主要更新: 1:增加AR.Global.GetUser() 方法返回当前登陆者的用户信息. 2:重写AR.Combobox 支持下拉树. 3:调整及扩展Input下拉的配置参数. 4:优化及新增AR. ...