程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> 其他數據庫知識 >> 更多數據庫知識 >> SQLServer 優化SQL語句 in 和not in的替代方案

SQLServer 優化SQL語句 in 和not in的替代方案

編輯:更多數據庫知識

但是用IN的SQL性能總是比較低的,從SQL執行的步驟來分析用IN的SQL與不用IN的SQL有以下區別:
SQL試圖將其轉換成多個表的連接,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接采用多個表的連接方式查詢。由此可見用IN的SQL至少多了一個轉換的過程。一般的SQL都可以轉換成功,但對於含有分組統計等方面的SQL就不能轉換了。 推薦在業務密集的SQL當中盡量不采用IN操作符
NOT IN 此操作是強列推薦不使用的,因為它不能應用表的索引。推薦用NOT EXISTS 或(外連接+判斷為空)方案代替
  在數據庫中有兩個表,一個是當前表Info(id,PName,remark,impdate,upstate),一個是備份數據表bakInfo(id,PName,remark,impdate,upstate),將當前表數據備份到備份表去,就涉及到not in 和in 操作了:
  首先,添加10萬條測試數據
復制代碼 代碼如下:
create procedure AddData
as
declare @id int
set @id=0
while(@id<100000)
begin
insert into dbo.Info(id,PName,remark,impdate,upstate)
values(@id,convert(varchar,@id)+'0','abc',getdate(),0)
set @id=@id+1
end
exec AddData

使用not in 和in操作:
復制代碼 代碼如下:
SET STATISTICS TIME ON
GO
--備份數據
insert into bakInfo(id,PName,remark,impdate,upstate)
select id,PName,remark,impdate,upstate from dbo.Info
where id not in(select id from dbo.bakInfo)
GO
SET STATISTICS TIME OFF

此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
  此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
  此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
  使用join連接替代方案:
復制代碼 代碼如下:
SET STATISTICS TIME ON
GO
--備份數據
insert into bakInfo(id,PName,remark,impdate,upstate)
select id,PName,remark,impdate,upstate from
(SELECT Info.id,Info.PName, Info.remark, Info.impdate,Info.upstate, bakInfo.id AS bakID
FROM Info left JOIN
bakInfo ON Info.id = bakInfo.id ) as t
where t.bakID is null and t.upstate=0
GO
SET STATISTICS TIME OFF;

  此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
  此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
--刪除當前表數據
復制代碼 代碼如下:
delete from Info
FROM Info INNER JOIN
bakInfo ON Info.id = bakInfo.id
where Info.upstate=1

  此操作執行時間:
復制代碼 代碼如下:
SQL Server 分析和編譯
  可以看出使用join方案比使用not in 和in執行時間要短很多了

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved