優化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萬條測試資料
01 | create procedure AddData |
02 | as |
03 | declare @id int |
04 | set @id=0 |
05 | while(@id<100000) |
06 | begin |
07 | insert into dbo.Info(id,PName,remark,impdate,upstate) |
08 | values(@id,convert(varchar,@id)+'0','abc',getdate(),0) |
09 | set @id=@id+1 |
10 | end |
11 |
12 | exec AddData |
使用not in 和in操作:
1 | SET STATISTICS TIME ON |
2 | GO |
3 | --備份資料 |
4 | insert into bakInfo(id,PName,remark,impdate,upstate) |
5 | select id,PName,remark,impdate,upstate from dbo.Info |
6 | where id not in(select id from dbo.bakInfo) |
7 | GO |
8 | SET STATISTICS TIME OFF |
此操作執行時間:
01 | SQL Server 分析和編譯時間: |
02 | CPU 時間 = 0 毫秒,佔用時間 = 3 毫秒。 |
03 |
04 | SQL Server 執行時間: |
05 | CPU 時間 = 453 毫秒,佔用時間 = 43045 毫秒。 |
06 |
07 | (100000 行受影響) |
08 | SQL Server 分析和編譯時間: |
09 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
10 |
11 |
12 | --更改當前表狀態 |
13 | update Info set upstate=1 where id in(select id from dbo.bakInfo) |
此操作執行時間:
01 | SQL Server 分析和編譯時間: |
02 | CPU 時間 = 62 毫秒,佔用時間 = 79 毫秒。 |
03 |
04 | SQL Server 執行時間: |
05 | CPU 時間 = 188 毫秒,佔用時間 = 318 毫秒。 |
06 |
07 | (100000 行受影響) |
08 | SQL Server 分析和編譯時間: |
09 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
10 |
11 |
12 |
13 | --刪除當前表資料 |
14 | delete from Info where upstate=1 and id in(select id from dbo.bakInfo) |
此操作執行時間:
1 | SQL Server 分析和編譯時間: |
2 | CPU 時間 = 183 毫秒,佔用時間 = 183 毫秒。 |
3 |
4 | SQL Server 執行時間: |
5 | CPU 時間 = 187 毫秒,佔用時間 = 1506 毫秒。 |
6 |
7 | (100000 行受影響) |
8 | SQL Server 分析和編譯時間: |
9 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
使用join連線替代方案:
01 | SET STATISTICS TIME ON |
02 | GO |
03 |
04 | --備份資料 |
05 | insert into bakInfo(id,PName,remark,impdate,upstate) |
06 | select id,PName,remark,impdate,upstate from |
07 | (SELECT Info.id,Info.PName, Info.remark, Info.impdate,Info.upstate, bakInfo.id AS bakID |
08 | FROM Info left JOIN |
09 | bakInfo ON Info.id = bakInfo.id ) as t |
10 | where t.bakID is null and t.upstate=0 |
11 | GO |
12 | SET STATISTICS TIME OFF; |
此操作執行時間:
1 | SQL Server 分析和編譯時間: |
2 | CPU 時間 = 247 毫秒,佔用時間 = 247 毫秒。 |
3 |
4 | SQL Server 執行時間: |
5 | CPU 時間 = 406 毫秒,佔用時間 = 475 毫秒。 |
6 |
7 | (100000 行受影響) |
8 | SQL Server 分析和編譯時間: |
9 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
1 | --更改當前表狀態 |
2 | update Info set upstate=1 |
3 | FROM Info INNER JOIN |
4 | bakInfo ON Info.id = bakInfo.id |
此操作執行時間:
1 | SQL Server 分析和編譯時間: |
2 | CPU 時間 = 4 毫秒,佔用時間 = 4 毫秒。 |
3 |
4 | SQL Server 執行時間: |
5 | CPU 時間 = 219 毫秒,佔用時間 = 259 毫秒。 |
6 |
7 | (100000 行受影響) |
8 | SQL Server 分析和編譯時間: |
9 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
1 | --刪除當前表資料 |
2 |
3 | delete from Info |
4 | FROM Info INNER JOIN |
5 | bakInfo ON Info.id = bakInfo.id |
6 | where Info.upstate=1 |
此操作執行時間:
1 | SQL Server 分析和編譯時間: |
2 | CPU 時間 = 177 毫秒,佔用時間 = 177 毫秒。 |
3 |
4 | SQL Server 執行時間: |
5 | CPU 時間 = 219 毫秒,佔用時間 = 550 毫秒。 |
6 |
7 | (100000 行受影響) |
8 | SQL Server 分析和編譯時間: |
9 | CPU 時間 = 0 毫秒,佔用時間 = 1 毫秒。 |
可以看出使用join方案比使用not in 和in執行時間要短很多了
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-628372/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL語句優化SQL優化
- MYSQL SQL語句優化MySql優化
- sql語句效能優化SQL優化
- 優化 SQL 語句的步驟優化SQL
- MySQL之SQL語句優化MySql優化
- [20201210]sql語句優化.txtSQL優化
- [20200320]SQL語句優化的困惑.txtSQL優化
- [20181114]一條sql語句的優化.txtSQL優化
- SQL優化案例-單表分頁語句的優化(八)SQL優化
- soar-PHP - SQL 語句優化器和重寫器的 PHP 擴充套件包、 方便框架中 SQL 語句調優PHPSQL優化套件框架
- Sql語句本身的優化-定位慢查詢SQL優化
- [20200324]SQL語句優化的困惑2.txtSQL優化
- SQL語句優化的原則與方法QOSQL優化
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- Java中如何解析SQL語句、格式化SQL語句、生成SQL語句?JavaSQL
- MySQL 52個SQL效能優化策略SQL語句彙總MySql優化
- [20211229]toad下優化sql語句注意的問題.txt優化SQL
- SQL語句最佳化SQL
- sql語句執行順序與效能優化(1)SQL優化
- MySql常用30種SQL查詢語句優化方法MySql優化
- Mysql 52條SQL語句效能優化策略彙總MySql優化
- MySql和簡單的sql語句MySql
- MySQL——優化ORDER BY語句MySql優化
- 騰訊雲TDSQL PostgreSQL版 -最佳實踐 |優化 SQL 語句SQL優化
- SSH框架控制檯輸出HQL語句和SQL語句的方法框架SQL
- 1.4 資料庫和常用SQL語句(正文)——MySQL資料庫命令和SQL語句資料庫MySql
- SQL語句SQL
- SQL語句IN的用法SQL
- sql 語句網路除錯和 sql 語句低層傳輸檢視SQL除錯
- 史上最全SQL優化方案SQL優化
- MySQL在大資料、高併發場景下的SQL語句優化和"最佳實踐"MySql大資料優化
- MySQL系列6 - join語句的優化MySql優化
- [20210205]警惕toad下優化直方圖相關sql語句.txt優化直方圖SQL
- ORACLE中sql語句----運算子的優先順序OracleSQL
- Oracle優化案例-單表分頁語句的優化(八)Oracle優化
- 【SQL】Oracle SQL join on語句and和where使用區別SQLOracle
- 【SQL】9 SQL INSERT INTO 語句SQL
- 【SQL】10 SQL UPDATE 語句SQL
- 【SQL】11 SQL DELETE 語句SQLdelete