2015-02-05 13 views
1

我試圖使我的查詢更高效。這是一個逐行檢查,並且由於沒有匹配的記錄,查詢很多次都不會進入更新點。我(編輯)知道認爲這樣做的最好方法是通過檢查是否有匹配,然後執行查詢。藉此以下真實案例例如,當我試圖最小化性能開銷:查詢性能 - 只在存在時選擇

/* LOOPING FROM MIN(ID) TILL MAX(ID) */ 
IF EXISTS(SELECT * 
      FROM InvoicesHC IHC 
       INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID 
       INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID 
       INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID 
       INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID 
      WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR) 
    BEGIN 
      UPDATE InvoicesHC SET InvoicePrice = @IGAS, PONumber = @POCO 
      FROM InvoicesHC IHC 
       INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID 
       INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID 
       INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID 
       INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID 
      WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR 
    END 

所以我第一次檢查,如果存在,那麼我實際執行它。這應該會使查詢運行得更快,但我不喜歡的事實是,我實際上覆制粘貼了相同的查詢 - 並在T-SQL中使用6次這樣的檢查,它變得非常大 - 比它更大其實應該看起來像我的意見。我的另一個關注點是性能:我已經將表連接在一起(現在只有4個內連接,但如果還有更多的話)來查找記錄是否匹配,然後再將它們連接在一起進行更新查詢。在我使用的小數據集中,這不是什麼大問題。但是如果這個逐行檢查應該執行數百萬次呢?

我相信應該有一個更有效的方式來創建這個聲明?有人有任何想法嗎?

謝謝。

+1

運行查詢兩次真的快?你有這個參考嗎? (我可以看到鎖定方面的一些好處,但我不認爲這會是一個很大的優化。) – 2015-02-05 12:40:46

+0

「我知道最好的方法是通過檢查是否有匹配,然後執行查詢。」 - 你怎麼知道?效率如何呢,那麼對於基於集合的操作,SQL通常是最好的 - 例如用單個語句更新所有記錄。 – Arvo 2015-02-05 12:44:51

+0

您是否害怕更新不存在的行? – joop 2015-02-05 12:45:49

回答

0

這應該是罰款:

 UPDATE InvoicesHC SET InvoicePrice = @IGAS, PONumber = @POCO 
     FROM InvoicesHC IHC 
      INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID 
      INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID 
      INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID 
      INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID 
     WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR 
0

,但我不喜歡的是,我居然複製粘貼相同 查詢了一遍 - 和T-SQL與6次這樣的檢查中, 就變得非常大

我認爲你應該使用Merge.Using合併減少這些重複查詢一次又一次。性能明智,至少它會比先前的代碼更好。

這只是演示。

MERGE InvoicesHC AS TRG 
USING (
SELECT InvoicesHC 
      FROM InvoicesHC IHC 
       INNER JOIN ContractSpecifications CS ON IHC.ContractSpecificationID = CS.ContractSpecificationID 
       INNER JOIN InstalledProductGroups IPG ON IPG.InstalledProductGroupID = CS.InstalledProductGroupID 
       INNER JOIN ProductGroups PG ON PG.ProductGroupID = IPG.ProductGroupID 
       INNER JOIN ContractFinYears CFY ON IHC.ContractFinYearID = CFY.ContractFinYearID 
      WHERE PG.ProductGroupID = 2 AND IHC.ContractNr = @CCODE AND CFY.ContractFinYear = @CYEAR 
)as SRC 
on trg.ContractNr=src.ContractNr 
When matched then 
    update 
     SET InvoicePrice = @IGAS, PONumber = @POCO; 
+2

這與'WHERE'的'UPDATE'語句沒有什麼不同,只是更復雜。充其量,優化器將創建與'UPDATE'語句相同的執行計劃 – 2015-02-05 12:53:08