2017-07-27 183 views
1

我在我們的數據庫DB中有一個60億行的表,這基本上是幾年內發生的所有事務。這有ColumnStore索引,其中包含所有列,並且沒有其他索引。有一個用戶界面,用戶將提供多個搜索條件(比如基於日期/金額/支付類型)等,我必須查詢此表並返回TOP 1000結果。SQL Server動態WHERE子句

我已經通過了以下建議的各種帖子。

  1. 使用具有各種if條件的變量並動態構建sql。使用sp_executesql的 - 的SQL變得非常混亂與所有這些邏輯

  2. 使用CoalesceIsNullCASEWHERE條款 - 這看起來簡潔,但非常緩慢。例如WHERE Total = 10需要(1秒),而Total = Coalesce(@Total, Total)需要幾分鐘才能運行。相同的延遲與IsNullCASE

我只是想確認是否有沒有其他辦法可以做到動態SQL除了上述2點的方法?欣賞你的想法。謝謝!

+4

這通常稱爲「全部通過」查詢。它們在搜索和其他用途中非常常見。這裏有一篇關於這個主題的偉大文章,討論了使這些工作快速完成的幾個選項。 http://www.sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries/ –

+2

Gail Shaw的另一篇文章... https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-confuse-the-sql-server-query-optimizer/ –

回答

0

這可能證明更有效。

WHERE 
    ((@Total IS NULL) OR ([email protected])) 
    AND 
    ((@Param2 IS NULL) OR ([email protected])) 
+1

「WHERE Total = @Total」需要1秒,因爲「WHERE(((@Total IS NULL )OR(Total = @ Total))「需要8秒 – user2980765

+0

最有可能出於同樣的原因您的原始查詢是慢....參數嗅探。在這種情況下,首先編譯和緩存的任何代碼將是最快的 –

+0

是的,OPTION(RECOMPILE)幾乎可以避免搜索過程中的異常延遲。 –

0

另一種方法是這樣的。

where Field1 = @aMandatoryParameter 
and (Field2 = @optionalPameter or @inputPameter is null) 
1

你在做什麼通常被稱爲「捕獲所有查詢」......有幾種方法可以解決這個問題。

1)動態SQL是一個有效的選項,但可能會超過kill。 2)可以工作,只要確保您添加選項(重新)和查詢結束。

你從1秒變爲幾分鐘的原因是因爲你從索引查找轉到索引掃描... OPTION(重新編譯)將允許優化器選擇查找計劃。

+0

添加OPTION(RECOMPILE)與((@Total IS NULL)OR(Total = @ Total))使動態WHERE不同。謝謝! – user2980765

+0

不客氣。 :) –