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

來源:互聯網
上載者:User

但是用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執行時間要短很多了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.