SQL 語句優化 --將Exists轉換成 inner join 語句來選擇正確的執行計劃

這段時間優化時,發現一個語句執行時間很長,效率很低,語句以下:html

複製代碼

select id,field015,field016,field017,field001,field020,field010,field014,field011,field013,field004,field018,
field005,field007,field003,null ,requestid from ufv3a7n71178865841875  tbalias where requestid in( select id from workflowbase wb where wb.isdelete<>1  and isfinished=0 ) and  
exists (select 'X' from Permissiondetail p where p.objid=tbalias.requestid and p.objtable='workflowbase' and ((p.userid='40282c48177be3a001177fefe73843d8') or (( p.isalluser=1 or p.orgid='40288a7d0f55fb5a010f569c2bf01205') 
and (p.minseclevel <= 10 and ((( p.maxseclevel is not null) and (10<= p.maxseclevel)) or (p.maxseclevel is null)))))) 
order by field017 desc,id descoop

複製代碼

執行計劃: 測試

執行結果: 優化

(1578 行受影響)
表 'workflowbase'。掃描計數 0,邏輯讀取 34932 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'permissiondetail'。掃描計數 8145,邏輯讀取 48196 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'ufv3a7n71178865841875'。掃描計數 1,邏輯讀取 576 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。spa

 

  將 exists語句轉換成inner join 語句,改爲後的語句以下:3d

複製代碼

select distinct tbalias.id,field015,field016,field017,field001,field020,field010,field014,field011,field013,field004,field018,
field005,field007,field003,null ,requestid from ufv3a7n71178865841875  tbalias
inner join workflowbase wb on wb.id=tbalias.requestid and wb.isdelete<>1  and isfinished=0 
inner join  Permissiondetail p on p.objid=tbalias.requestid and p.objtable='workflowbase' and 
((p.userid='40282c48177be3a001177fefe73843d8') or (( p.isalluser=1 or p.orgid='40288a7d0f55fb5a010f569c2bf01205') 
and (p.minseclevel <= 10 and ((( p.maxseclevel is not null) and (10<= p.maxseclevel)) or (p.maxseclevel is null)))))
order by field017 desc,id deschtm

複製代碼

執行計劃:blog

執行結果:get

(1578 行受影響)
表 'permissiondetail'。掃描計數 2988,邏輯讀取 17298 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'Worktable'。掃描計數 0,邏輯讀取 0 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'ufv3a7n71178865841875'。掃描計數 1,邏輯讀取 576 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。
表 'workflowbase'。掃描計數 1,邏輯讀取 1425 次,物理讀取 0 次,預讀 0 次,lob 邏輯讀取 0 次,lob 物理讀取 0 次,lob 預讀 0 次。workflow

 

   經過使用 inner join 替換 exists ,咱們發現執行計劃裏將 哈希聯結(Hash join)換成了 嵌套循環(Nested Loops) ,IO次數明細減小。

總結:

     之前寫過一優化文章" SQL優化--使用 EXISTS 代替 IN 和 關聯查詢(inner join) ",提示用exists替換inner join ,這個替換是有前提條件,要通過測試的,今天咱們又使用 inner join 替換 exists ,也是在實際狀況中的使用,二者沒有具體的公式

      目的:是在特定狀況下讓優化器能使用正確的執行計劃。

相關文章
相關標籤/搜索