曲演杂坛--EXISTS语句
通常在我写EXISTS语句时,我会写成IF EXISTS(SELECT TOP(1) 1 FROM XXX),也没细细考究过为什么要这么写,只是隐约认为这样写没有啥问题,那今天就深究下吧!
首先准备测试测试数据
USE [TestDB1]
GO
CREATE TABLE TB1001
(
ID INT IDENTITY(1,1),
C1 VARCHAR(200),
CONSTRAINT PK_TB1001_ID PRIMARY KEY(ID)
)
GO
CREATE INDEX IDX_ID ON TB1001(ID) GO
INSERT INTO TB1001(C1)
SELECT name FROM sys.columns
GO
其中需要注意下索引IDX_ID, 虽然ID已经是主键索引,但仍创建一个非聚集索引以供后续测试。
通常我们在写EXISTS语句时,一个纠结点是要不要使用TOP,另外一个纠结点是SELECT 语句中的返回列,因此构造测试语句如下:
IF EXISTS(SELECT 1 FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END IF EXISTS(SELECT TOP(1) 1 FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END IF EXISTS(SELECT TOP(10) 1 FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END IF EXISTS(SELECT * FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END IF EXISTS(SELECT ID FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END IF EXISTS(SELECT C1 FROM [dbo].[TB1001] WHERE ID>10)
BEGIN
PRINT 1
END
以上语句各种写法,但最终生成的执行计划都一样,因此执行效率也一样:
对于IF EXISTS(SELECT C1 FROM [dbo].[TB1001] WHERE ID>10)语句,索引IDX_ID并没有包含C1列的数据,但查询仍使用IDX_ID索引,证明查询并不需要访问C1列的数据
从上面的操作运算符来看,可以得到以下两个结论:
1. 无论是TOP(1)还是TOP(10)或不使用TOP,执行计划中都没有TOP的操作,即使SQL语句中写明TOP(1)也会被忽略,因此TOP并不影响生成执行计划;
2. 无论使用SELECT 1 或者使用SELECT * 又或者使用SELECT C1 等,运算符都没有返回列信息(OUTPUT LIST), 即EXISTS并不关心返回数据的内容,只关心有没有数据,因此SELECT部分的内容也不影响生成执行计划;
--========================================================
PS: Seek Keys[1] 并不代表只返回一行数据,如对于查询:
SELECT TOP(10) * FROM [dbo].[TB1001] WHERE ID>10
其生成的执行计划为:
================================================
曲演杂坛--EXISTS语句的更多相关文章
- 曲演杂坛--一条DELETE引发的思考
原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...
- 曲演杂坛--为什么SELECT语句会被其他SELECT阻塞?
很多刚入门的DBA在捕获阻塞得时候,会问这么一个问题“为什么这个SELECT语句被那个SELECT语句阻塞了,难道不是共享锁么?” 让我们来做个小测试,首先准备一些测试数据: --========== ...
- 曲演杂坛--当ROW_NUMBER遇到TOP
值班期间研发同事打来电话,说应用有超时,上服务器上检查发现有SQL大批量地执行,该SQL消耗IO资源较多,导致服务器存在IO瓶颈,细看SQL,发现自己都被整蒙了,不知道这SQL是要干啥,处理完问题赶紧 ...
- 曲演杂坛--使用CTE时踩的小坑:No Join Predicate
在一次系统优化中,意外发现一个比较“坑”的SQL,拿出来供大家分享. 生成演示数据: --====================================== --检查测试表是否存在 IF(O ...
- 曲演杂坛--SQLCMD下执行命令失败但没有任何错误提示的坑
今天使用SQLCMD导入到SQL SERVER数据库中,看着数据文件都成功执行,但是意外发现有一个文件数据没有成功导入,但执行不报错,很容易导致问题被忽略. 使用存在问题的文件做下测试,从界面上看几行 ...
- 曲演杂坛--Update的小测试
今天偶然想起一个UPDATE相关的小问题,正常情况下,如果我们将UPDATE改写成与之对应的SELECT语句,其SELECT查询结果应与UPDATE的目标表存在一对一的关系,例如: 对于UPDATE语 ...
- 曲演杂坛--使用TRY CATCH应该注意的一个小细节
群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象 --============================================ ...
- 曲演杂坛--蛋疼的ROW_NUMBER函数
使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...
- 曲演杂坛--特殊字符/生僻字与varchar
对于中文版的SQL SERVER,默认安装后使用的默认排序规则为Chinese_PRC_CI_AS,在此排序规则下,使用varchar类型来可以“正常存取”存放中文字符以及一些东南亚国家的字符,同时v ...
随机推荐
- java基础知识点复习
第一天: JRE.JDK是什么? Jre java运行环境.Jre = java虚拟机+核心类库(辅助java运行的文件) Jdk:java开发工具集jdk = jre+java的开发工具 2. 配置 ...
- [Tomcat 源码分析系列] (附件) : setclasspath.bat 脚本
@echo off rem Licensed to the Apache Software Foundation (ASF) under one or more rem contributor lic ...
- 一个PHP日历程序
<?php //<-------处理通过GET方法提交的变量;开始--------> if($HTTP_GET_VARS[year]=="") { ...
- 关于c#中的console用法大全
C#之Console Console.Write 表示向控制台直接写入字符串,不进行换行,可继续接着前面的字符写入.Console.WriteLine 表示向控制台写入字符串后换行.Conso ...
- POJ 1661 Help Jimmy LIS DP
http://poj.org/problem?id=1661 对板按高度排序后. dp[i][0]表示现在站在第i块板上,向左跑了,的状态,记录下时间和其他信息. O(n^2)LIS: 唯一的麻烦就是 ...
- Selenium2+python自动化7-xpath定位
前言 在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语法. ...
- js alert重写,适用于手机端,改自于网上的代码
<!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...
- gtest vs2015配置
1. 下载gtest https://github.com/google/googletest 2. 解压文件 使用vs2015 打开googletest-master\googletest\msvc ...
- springMVC框架中,在hib-config.xml配置sqlserver2008数据库连接的代码
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> ...
- fedora 安装vmwear
Fedora 13下安装后缀为bundle文件,网上的说法很多,最普遍的方法是: 你的登陆名为TEST那么就将要安装的文件放在TEST目录下,不要放到目录下的子目录上面,否则不能运行.然后执行 第一步 ...