SQL優化--使用 EXISTS 代替 IN 和 inner join來選擇正確的執行計劃

在使用Exists時,若是能正確使用,有時會提升查詢速度:sql

      1,使用Exists代替inner join性能

      2,使用Exists代替 inspa

 

  1,使用Exists代替inner join例子:

     在通常寫sql語句時一般會遇到以下語句:blog

      兩個錶鏈接時,取一個表的數據,通常的寫法經過關聯查詢(inner join):      workflow

select a.id, a.workflowid,a.operator,a.stepid
from  dbo.[[zping.com]]] a
inner join workflowbase b on a.workflowid=b.id
and operator='4028814111ad9dc10111afc134f10041'io

 

查詢結果:table

(1327 行受影響)
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'workflowbase'。掃描計數 1,邏輯讀取 293 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 '[zping.com]'。掃描計數 1,邏輯讀取 1339 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。效率

 

   還有一種寫法使用exists來取數據select

select a.id,a.workflowid,a.operator ,a.stepid
from  dbo.[[zping.com]]] a where exists
(select 'X' from workflowbase b where a.workflowid=b.id)
and operator='4028814111ad9dc10111afc134f10041'sql語句

 執行結果:  

(1327 行受影響)
表 '[zping.com]'。掃描計數 1,邏輯讀取 1339 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'workflowbase'。掃描計數 1,邏輯讀取 291 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

 

   這裏兩着的IO次數,EXISTS比inner join少 2個IO, 對比執行計劃成本不同, 看看兩着的差別:  

 

 

   這時咱們發現使用EXISTS要比inner join效率稍微高一下。  
     2,使用Exists代替 in

      要求:編寫workflowbase表中id不在表中dbo.[[zping.com]]]的行:      

       通常的寫法:

select * from workflowbase 
 where  id not in (
select  a.workflowid
from  dbo.[[zping.com]]] a )

執行結果:


(1 行受影響)
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 '[zping.com]'。掃描計數 5,邏輯讀取 56952 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'workflowbase'。掃描計數 3,邏輯讀取 1589 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

    使用Existsl來寫:

select * from workflowbase b
 where not exists(
select 'X'
from  dbo.[[zping.com]]] a where a.workflowid=b.id )

   看看執行結果

(1 行受影響)
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 '[zping.com]'。掃描計數 3,邏輯讀取 18984 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'workflowbase'。掃描計數 3,邏輯讀取 1589 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。

  兩個io的差距:56952+1589=58541次 (使用IN)

                     18984+1589=20573次  (使用Exists)

   使用exists是in的2.8倍,查詢性能提升很大。

 

 

   EXISTS 使查詢更爲迅速,由於RDBMS核心模塊將在子查詢的條件一旦知足後,馬上返回結果。

相關文章
相關標籤/搜索