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

其生成的执行计划为:

时间: 2024-12-20 07:46:48

EXISTS语句的相关文章

当转换in 与exists语句时碰上group by

有如下语句,想把他转换成exists语句:外表内表用的都是同一张表 select * from shuxue_new as a where id in  (select max(id) from shuxue_new group by userid); select * from shuxue_new as a where id not in  (select max(id) from shuxue_new group by userid); 于是: select * from shuxue_n

使用EXISTS语句注意点

1.使用EXISTS语句,其目标列一般用“*”,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义. 2.使用EXISTS语句一定要注意上下两个表之间要建立联系. 例如,查询所有选修了1号课程的学生姓名. 错误做法是: select Sname From student where Exists ( select * from SC WHERE Cno='1'; ) 因为二者之间没有建立联系.所有查询失败. 正确做法是 select Sname From student where

oracle中的exists 和not exists 用法 in与exists语句的效率问题

博文来源(oracle中的exists 和not exists 用法):http://chenshuai365-163-com.iteye.com/blog/1003247 博文来源(  in与exists语句的效率问题):http://www.cnblogs.com/iceword/archive/2011/02/15/1955337.html (一) exists (sql 返回结果集为真) not exists (sql 不返回结果集为真) 如下: 表A ID NAME 1    A1 2

ORACLE in与exists语句的区别(一)

(转载:https://www.cnblogs.com/iceword/archive/2011/02/15/1955337.html) select * from Awhere id in(select id from B) 以上查询使用了in语句,in()只执行一次,它查出B表中的所有id字段并缓存起来.之后,检查A表的id是否与B表中的id相等,如果相等则将A表的记录加入结果集中,直到遍历完A表的所有记录.它的查询过程类似于以下过程 List resultSet=[];Array A=(s

sql语句:if exists语句使用

if exists(select * from test.dbo.test1 where a='1') begin print('exists ') end else begin print('no exists ') end go

SQL语句中exists和in的区别

转自https://www.cnblogs.com/liyasong/p/sql_in_exists.html 和 http://blog.csdn.net/lick4050312/article/details/4476333 表展示 查询中涉及到的两个表,一个user和一个order表,具体表的内容如下: user表: order表: in 一.确定给定的值是否与子查询或列表中的值相匹配.in在查询的时候,首先查询子查询的表,然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选.所以相对内表

Sql 语句中 IN 和 EXISTS 的区别及应用

演示demo表: student表 DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `stuid` varchar(16) NOT NULL COMMENT '学号', `stunm` varchar(20) NOT NULL COMMENT '学生姓名', PRIMARY KEY (`stuid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ------------------------

mysql exists 和 in的效率比较

这条语句适用于a表比b表大的情况 select * from ecs_goods a where cat_id in(select cat_id from ecs_category); 这条语句适用于b表比a表大的情况select * from ecs_goods a where EXISTS(select cat_id from ecs_category b where a.cat_id = b.cat_id); 原因:(转发) select * from Awhere id in(selec

关于Oracle中in,exists 与 not in, not exists

文章简要的讨论了in,exists 与 not in, not exists在使用中的问题,主要是关键字的选择,SQL的优化 *注:下面示例都是用Oracle内置用户的表,如果安装Oracle时没有选择不安装数据库示例表应该都会安装的 1.IN和EXISTS IN语句: SELECT * FROM hr.employees t1 WHERE t1.employee_id IN ( SELECT t2.employee_id FROM hr.job_history t2 ); EXISTS语句: