国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > SQL Server > 正文

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

2024-08-31 00:58:59
字體:
來源:轉載
供稿:網友
但是用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 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 3 毫秒。
SQL Server 執行時間:
CPU 時間 = 453 毫秒,占用時間 = 43045 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
--更改當前表狀態
update Info set upstate=1 where id in(select id from dbo.bakInfo)


  此操作執行時間:

復制代碼 代碼如下:


SQL Server 分析和編譯時間:
CPU 時間 = 62 毫秒,占用時間 = 79 毫秒。
SQL Server 執行時間:
CPU 時間 = 188 毫秒,占用時間 = 318 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
--刪除當前表數據
delete from Info where upstate=1 and id in(select id from dbo.bakInfo)


  此操作執行時間:

復制代碼 代碼如下:


SQL Server 分析和編譯時間:
CPU 時間 = 183 毫秒,占用時間 = 183 毫秒。
SQL Server 執行時間:
CPU 時間 = 187 毫秒,占用時間 = 1506 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。


  使用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 分析和編譯時間:
CPU 時間 = 247 毫秒,占用時間 = 247 毫秒。
SQL Server 執行時間:
CPU 時間 = 406 毫秒,占用時間 = 475 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。
--更改當前表狀態
update Info set upstate=1
FROM Info INNER JOIN
bakInfo ON Info.id = bakInfo.id


  此操作執行時間:

復制代碼 代碼如下:


SQL Server 分析和編譯時間:
CPU 時間 = 4 毫秒,占用時間 = 4 毫秒。
SQL Server 執行時間:
CPU 時間 = 219 毫秒,占用時間 = 259 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。


--刪除當前表數據

復制代碼 代碼如下:


delete from Info
FROM Info INNER JOIN
bakInfo ON Info.id = bakInfo.id
where Info.upstate=1


  此操作執行時間:

復制代碼 代碼如下:


SQL Server 分析和編譯時間:
CPU 時間 = 177 毫秒,占用時間 = 177 毫秒。
SQL Server 執行時間:
CPU 時間 = 219 毫秒,占用時間 = 550 毫秒。
(100000 行受影響)
SQL Server 分析和編譯時間:
CPU 時間 = 0 毫秒,占用時間 = 1 毫秒。


  可以看出使用join方案比使用not in 和in執行時間要短很多了
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 固镇县| 泾源县| 洛浦县| 汝州市| 江门市| 靖安县| 兴海县| 宜君县| 民丰县| 聂拉木县| 舟山市| 昌乐县| 黄浦区| 固镇县| 华阴市| 漠河县| 腾冲县| 通河县| 西藏| 信阳市| 阿瓦提县| 达孜县| 天台县| 颍上县| 霍山县| 台安县| 巫溪县| 梓潼县| 濮阳县| 沈丘县| 长海县| 沁阳市| 北安市| 安康市| 凤冈县| 璧山县| 普宁市| 澳门| 鄂温| 灵台县| 花莲县|