網站連結

最新回應

在MSDN FORUM 小朱 多條件查詢SQL 查詢的討論中,
說明到關於效能的問題,Dotjum這邊就就使用 執行計畫 作一各小小的比較,
(這邊強調一下,因為Dotjum不太會用 執行計畫 評估成本,
所以是直接看最後一個數據,若有錯誤,還請各位多多指教)



這次多條件的查詢,Dotjum增加了再看 SubText 中的 Procedure 中,
有看到另一種多條建的查詢語法使用 IsNull ,話不多說,
就來看整個比較,首先我使用了 AdventureWorks 資料庫,總共資料約 121317 筆資料。
use AdventureWorks
-- 總共 121317
SELECT COUNT(*)  FROM  
 Sales.SalesOrderDetail

image

1.第一種比較就直接是命令字串的方式

--直接串命令方式
SELECT *  FROM  
 Sales.SalesOrderDetail
WHERE CarrierTrackingNumber =  '4911-403C-98'
/*
AND
ProductID  = 776
*/
2.採用 CASE WEHN 的方式
DECLARE @CarrierTrackingNumber varchar(20)
SET @CarrierTrackingNumber =  '4911-403C-98'
DECLARE @ProductID int
SET @ProductID =  0

SELECT *  FROM  
 Sales.SalesOrderDetail
WHERE CarrierTrackingNumber = 
CASE  @CarrierTrackingNumber 
WHEN '' THEN CarrierTrackingNumber ELSE @CarrierTrackingNumber END
AND
ProductID  = 
CASE  @ProductID 
WHEN 0 THEN ProductID  ELSE @ProductID  END
 
3.使用 IS NULL
DECLARE @CarrierTrackingNumber varchar(20)
SET @CarrierTrackingNumber =  '4911-403C-98'
DECLARE @ProductID int
SET @ProductID =  null

SELECT *  FROM  
 Sales.SalesOrderDetail
WHERE
( CarrierTrackingNumber = 
   @CarrierTrackingNumber OR @CarrierTrackingNumber IS NULL)
 AND
(ProductID  =  @ProductID OR @ProductID IS NULL)
 
依序是 1.直接串指令 2.CASE WHEN  3. OR ISNULL 方式比較
image imageimage
Dotjum 以子樹成本來看的話(如果有專家可以指正的錯誤的觀念還麻煩請多指教),
1.直接串指令是最快 2. OR ISNULL 次快 3. CASE WHEN 最慢

但因為單機執行,也無法就決定性的說哪一個比較好,但Dotjum自己的觀念是如果能夠把參數都決定好,

在程式上比較好控制(這是我自己覺得的),當然如果做好一個專門串指令的Class,或許也不會那麼複雜,

效能方面也可以感覺起來比較好,還請各位多給指教。

回應

  • 小朱 2008/3/11 下午 06:48 回覆

    # re: 多條件判斷查詢使用三種方法 1.直接串指令 2.TSQL WHEN 3.Is Null 效能比較

    我用了你的方法去測試,有幾點有趣的地方:

    若用 CASE 來做的話,如果資料表中有 PK,會變成使用 Clustered Index Scan,沒有 PK 或索引的話,會是 Table Scan,這兩者都不好,因為都沒有用到索引 (Clustered Index 在搜尋上效能不好,但在彙總時就會很好)。
    若用 WHERE 直接判斷,它會去找 index,如果有的話就是 index seek,這個效能就會比較好,沒有的話則是 Table Scan,則效能一樣也不好。
    OR 我沒測,但我想和 WHERE 是差不多,但多了一個 OR 判斷的動作。



    這些都可以由執行計畫的圖中看的出來。

    查詢條件應盡可能的分散到索引上,這樣速度才會夠快,如果還是不夠快就是 I/O 的問題了。


*標 題:

*姓 名:

 電子郵件: (將不會被顯示)

 個人網頁:

*回應

登入後使用進階評論

Please add 2 and 6 and type the answer here: