zoukankan      html  css  js  c++  java
  • SQL Server 性能优化之——T-SQL NOT IN 和 NOT Exists

    这次介绍一下T-SQL中“Not IN” 和“Not Exists”的优化。

    Not IN  Not Exists 命令 :

    有些情况下,需要select/update/delete 操作孤立数据。孤立数据:不存在主表中而存在其关联表中。

    操作这样的数据,一般第一反应是利用“Not in” 或 “Not Exists”命令。使用Not IN会严重影响性能,因为这个命令会逐一检查每个记录,就会造成资源紧张,尤其是当对大数据进行更新和删除操作时,可能导致资源被这些操作锁住。

    选择NOT IN 还是 NOT Exists

    现在SQL Server 中有两个命令可以使用大数据的插入、更新、删除操作,性能方面比NOT IN有很大的提高,语法简单比NOT Exists好很多,写出来的语句看上去很清爽。 现在就请它们闪亮登场,Merge 和 Except。

    例子:

    首先创建两个表

    use [MyTest]
    create table Test1 ([id] int, [name] varchar(20))
    create table Test2 ([id] int, [name] varchar(20), [address] varchar(100))
    declare @RowC int
    declare @Name varchar(20)
    set @RowC = 0
    while @RowC < 400000
    Begin
    set @Name = 'TestName' + CAST(@RowC as varchar(10))
    insert into Test1(id, name) values(@RowC, @Name)
    set @RowC = @RowC+1
    end
    declare @RowC int
    declare @Name varchar(20)
    declare @Address varchar(100)
    set @RowC = 0
    while @RowC < 500000
    Begin
    set @Name = 'TestName' + CAST(@RowC as varchar(10))
    set @Address = 'TestAddress' + CAST(@RowC as varchar(10))
    insert into Test2([id], [name], [address]) values(@RowC, @Name, @Address)
    set @RowC = @RowC+1
    end
    SELECT [name] FROM Test2 where [name] not in (select [name] from Test1)
    UPDATE Test2 SET [name] =N'New_Name' where [name] not in (select [name] from Test1)
    DELETE Test2 FROM Test2 where [name] not in (select [name] from Test1)
    merge Test2 T using (select name from Test2 except select name from Test1 )S on t.name=s.name
    when matched then update SET name=N'New_Name' ;
    merge Test2 T using (select name from Test2 except select name from Test1 )S on t.name=s.name
    when matched then delete ;
    SELECT * FROM Test2 S where not exists (select 1 from Test2 inner join Test1 on Test2.name=Test1.name and Test2.name=s.name)

    注意,上面还是有一部分使用了Not Exists:

    SELECT name FROM Test2 S where not exists (select 1 from Test2 inner join Test1 on Test2.name=Test1.name and Test2.name=s.name)

    现在需要使用简洁的Except:

     

    select name from Test1 except select name from Test2

  • 相关阅读:
    codeforces 455B A Lot of Games(博弈,字典树)
    HDU 4825 Xor Sum(二进制的字典树,数组模拟)
    hdu 1800 Flying to the Mars(简单模拟,string,字符串)
    codeforces 425A Sereja and Swaps(模拟,vector,枚举区间)
    codeforces 425B Sereja and Table(状态压缩,也可以数组模拟)
    HDU 4148 Length of S(n)(字符串)
    codeforces 439D Devu and Partitioning of the Array(有深度的模拟)
    浅谈sass
    京东楼层案例思维逻辑分析
    浅谈localStorage和sessionStorage
  • 原文地址:https://www.cnblogs.com/zoro-zero/p/7681402.html
Copyright © 2011-2022 走看看