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

2021-06-05 06:39:12 字數 2450 閱讀 9852

但是用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萬條測試資料

使用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

cpu 時間 = 0 毫秒,占用時間 = 3 毫秒。

cpu 時間 = 453 毫秒,占用時間 = 43045 毫秒。

(100000 行受影響)

cpu 時間 = 0 毫秒,占用時間 = 1 毫秒。

--更改當前表狀態

update info set upstate=1 where id in(select id from dbo.bakinfo)

cpu 時間 = 62 毫秒,占用時間 = 79 毫秒。

cpu 時間 = 188 毫秒,占用時間 = 318 毫秒。

(100000 行受影響)

cpu 時間 = 0 毫秒,占用時間 = 1 毫秒。

--刪除當前表資料

delete from info where upstate=1 and id in(select id from dbo.bakinfo)

cpu 時間 = 183 毫秒,占用時間 = 183 毫秒。

cpu 時間 = 187 毫秒,占用時間 = 1506 毫秒。

(100000 行受影響)

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;

cpu 時間 = 247 毫秒,占用時間 = 247 毫秒。

cpu 時間 = 406 毫秒,占用時間 = 475 毫秒。

(100000 行受影響)

cpu 時間 = 0 毫秒,占用時間 = 1 毫秒。

--更改當前表狀態

update info set upstate=1

from info inner join

bakinfo on info.id = bakinfo.id

cpu 時間 = 4 毫秒,占用時間 = 4 毫秒。

cpu 時間 = 219 毫秒,占用時間 = 259 毫秒。

(100000 行受影響)

cpu 時間 = 0 毫秒,占用時間 = 1 毫秒。

--刪除當前表資料

delete from info

from info inner join

bakinfo on info.id = bakinfo.id

where info.upstate=1

cpu 時間 = 177 毫秒,占用時間 = 177 毫秒。

cpu 時間 = 219 毫秒,占用時間 = 550 毫秒。

(100000 行受影響)

cpu 時間 = 0 毫秒,占用時間 = 1 毫秒。

可以看出使用join方案比使用not in 和in執行時間要短很多了

原文出處:

sql優化 in 和 not in 語句

why?in 和 not in 是比較常用的關鍵字,為什麼要盡量避免呢?1 效率低 可以參看我之前遇到的乙個例子 小問題筆記 九 sql語句not in 效率低,用 not exists試試 2 容易出現問題,或查詢結果有誤 不能更嚴重的缺點 以 in 為例。建兩個表 test1 和 test2 c...

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

最近做乙個 要求a庫中的aa表匯入到另乙個b庫中的aa表中。並且不能重複匯入。因為a.aa中70多萬條記錄,而且以後可以會有新增新記錄。所不可能一次性導完。所以又在b庫中建立乙個表用於記錄匯入過的記錄。剛開始用 not in 來實現。在但發現在實現過程中經常超時。在網上找了半天。發現下面的文章。原文...

SQL語句中的NOT IN 的優化

sql語句中的in和not in子查詢理解起來很直觀,和實際的業務也很匹配,所有經常被開發人員使用,資料量不大的表還好,如果資料量太大將導致效能問題。原sql select count distinct t.id from task t where t.tenant key tp18squme1 a...