1. 程式人生 > >優化SQL 語句 in 和not in 的替代方案

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

用IN寫出來的SQL的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。

但是用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操作:

1 2 3 4 5 6 7 8 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

  此操作執行時間:

1 2 3 4 5 6 7 8 9 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)

  此操作執行時間:

1 2 3 4 5 6 7 8 9 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)

  此操作執行時間:

1 2 3 4 5 6 7 SQL Server 分析和編譯時間: CPU 時間 = 183 毫秒,佔用時間 = 183 毫秒。 SQL Server 執行時間: CPU 時間 = 187 毫秒,佔用時間 = 1506 毫秒。 (100000 行受影響) SQL Server 分析和編譯時間: CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。

  使用join連線替代方案:

1 2 3 4 5 6 7 8 9 10 11 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;


  此操作執行時間:

1 2 3 4 5 6 7 SQL Server 分析和編譯時間: CPU 時間 = 247 毫秒,佔用時間 = 247 毫秒。 SQL Server 執行時間: CPU 時間 = 406 毫秒,佔用時間 = 475 毫秒。 (100000 行受影響) SQL Server 分析和編譯時間: CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。
1 2 3 4 --更改當前表狀態 update Info set upstate=1 FROM         Info INNER JOIN bakInfo ON Info.id = bakInfo.id

  此操作執行時間:

1 2 3 4 5 6 7 SQL Server 分析和編譯時間:

相關推薦

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

用IN寫出來的SQL的優點是比較容易寫及清晰易懂,這比較適合現代軟體開發的風格。 但是用IN的SQL效能總是比較低的,從SQL執行的步驟來分析用IN的SQL與不用IN的SQL有以下區別: SQL試圖將其轉換成多個表的連線,如果轉換不成功則先執行IN裡面的子查詢,再查詢外層的表記錄,如果轉換成功則直接採用多個

面試被問之-----sql優化in與exists的區別 Mysql中 in or exists not exists not in區別 (網路整理) Sql語句INexists的區別及應用 [筆記] SQL效能優化 - 避免使用 IN NOT IN

曾經一次去面試,被問及in與exists的區別,記得當時是這麼回答的:''in後面接子查詢或者(xx,xx,xx,,,),exists後面需要一個true或者false的結果",當然這麼說也不算錯,但別人想聽的是sql優化相關,肯定是效率的問題,只是那個時候確實不知道它們在sql優化上的區別,只知道用in會進

SQL優化- innot in

audit roc RoCE AI 時間 pro 執行 code ESS in不會導致索引失效,但最終數據庫會將in語句解析為or語句,eg: select * from T_MAIN_PROCESS t where t.audit_status_code in (‘05‘

數據庫優化技巧之innot in

寫法 exists art null data class -s ack size 在編寫SQL語句時,假設要實現一張表有而另外一張表沒有的數據時。 通常第一直覺的寫法是: select * from table1 where table1.id not in(s

sql中existsnot exists用法 容易in not in 混淆

看專案程式碼時遇到,記錄下 select * from A where id in(select id from B) 以上查詢使用了in語句,in()只執行一次,它查出B表中的所有id欄位並快取起來. 然後,檢查A表的id是否與B表中的id相等, 如果相等則將A表的記

SQL中EXCEPTNot in的區別?

初始化兩張表: CREATE TABLE tb1(ID int) INSERT tb1SELECT NULLUNIONALLSELECT NULLUNIONALLSELECT NULLUNIONALLSELECT 1UNIONALLSELECT 2UNIONALLSELECT

sql語句中替換Not In 的方法

insert into stuinfo(Username,Objjc,Sex,Classid) values ('李明','文科','女','123')insert into stuinfo(Username,Objjc,Sex,Classid)values ('王二','理科','男','121')inse

SQL中EXCEPTNot in的區別

SQL中EXCEPT和Not in的區別? 我們一起來看看。 初始化兩張表: CREATE TABLE tb1(ID int)  INSERT tb1          SELECT NULL UNION  ALL          SELECT NULL UNION 

多個欄位的in not in 及其替代寫法(exists,not exists)

【轉載】先說基本情況:資料庫:DB2 8.2,SQL Server 2005 Express表a  有欄位:aaa,bbb,還可能有其他欄位。記錄條數:3764表b  有欄位:aaa,bbb,還可能有其他欄位。記錄條數:4127就是表a的欄位aaa跟表b的欄位aaa有對應關係

Oracle中使用join表連線查詢代替 innot in 查詢

首先,在oracle中效率排行:表連線>exist>not exist>in>not in,而且使用in查詢會有查詢條件數量不能超過1000的限制;因此如果簡單提高效率可以用exist代替in進行操作,當然換成表連線可以更快地提高效率,具體是用le

oracle 子查詢中null的問題(in not in

這裡的in後面的句子可以理解為or拼接,簡單舉例即 in (9566,9839,null)可以等價於mgr=9566 or mgr=9839 or mgr=null, not in (9566,9839,null)可以等價於not(mgr=9566 or mgr=9839 o

Elasticsearch 查詢in not in 的實現方式

 最近用到ES查詢,因用的是Java寫的,需要實現一個需求: 過濾一部分id, 查詢時不需要查出來。 既然需要不包含,那麼首先需要實現包含的方式(精確完全匹配),這裡我們要用到的是termQuery首先看下ES Bool聯合查詢的屬性:bool聯合查詢: must,shoul

hibernate關於innot in的查詢

方法一: @Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true) public List<OpUsrrole> OpUsrroleExList(List<OpUsrrole> grprole) { Arra

關於hql中的in not in

今天下午在碼程式碼的時候碰到了in 和not in的使用,然後我使用的是公司封裝的方法 發現公司封裝的方法並不支援in 和not  in,我還死腦筋的鑽了半天,簡直浪費時間。 晚上回到房裡怒測試hibernate自身的方法,發現這簡直太簡單了!!!!! 這裡就不提供程式碼塊

hive例項講解實現innot in子句

目前hive不支援 in或not in 中包含查詢子句的語法,所以只能通過left join實現。 假設有一個登陸表login(當天登陸記錄,只有一個uid),和一個使用者登錄檔regusers(當天註冊使用者,欄位只有一個uid),這兩個表都包含一個欄位,uid。

避免使用 IN NOT IN

IN 和 NOT IN 是比較常用的關鍵字,為什麼要儘量避免呢? 1、效率低  2、容易出現問題,或查詢結果有誤 (不能更嚴重的缺點) 以 IN 為例。建兩個表:test1 和 test2 create table test1 (id1 int) create table test2 (id2

mysql的innot in的用法(特別注意not in結果集中不能有null)

注意: 1. not in的結果集中出現null則查詢結果為null; 例如下面sql中,含有list中null值,無法正確查詢結果; SELECT COUNT(name) FROM CVE WHERE name NOT IN ('CVE-1999-000

Sql語句優化之用exists、not exists替代innot in

在許多基於基礎表的查詢中,為了滿足一個條件,往往需要對另一個表進行聯接。在這種情況下, 使用exists(或not exists)通常將提高查詢的效率。在子查詢中,not in子句將執行一個內部的排序和合並。無論在哪種情況下,not in都是最低效的 (因為它對子查詢中的表

sql語句學習(NOT EXISTS NOT IN

exist car rod cto from log del sele tinc NOT EXISTS SELECT   a.*FROM   t_user aWHERE   a.id_card LIKE ‘%3203821995100%‘AND NOT EXISTS ( S

SQL語句not in not exist的區別

in和exists in 是把外表和內表作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。一直以來認為exists比in效率高的說法是不準確的。 如果查詢的兩個表大小相當,那麼用in和exists差別不大。 如果兩個表中一個較小,一個是