zoukankan      html  css  js  c++  java
  • 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

    其生成的执行计划为:

  • 相关阅读:
    unity c# 获取系统时间
    如果你想让继承MonoBehaviour的类变成Singleten
    关于程序员
    开始养成记录的习惯吧
    关于结构体的赋值问题
    数学中的集合,群,环,域
    励志
    [编程题] 进制均值
    javaEE 入门
    jsp内置对象2
  • 原文地址:https://www.cnblogs.com/lykbk/p/saeresrersrwe453454545454.html
Copyright © 2011-2022 走看看