2012-11-05 46 views
1

我使用SQL Server 2005的如何提高使用參數的SQL查詢的性能?

我有一個問題,執行這樣的

DECLARE @Param1 BIT 
SET @Param1 = 1 

SELECT 
    t1.Col1, 
    t1.Col2 
FROM 
    Table1 t1 
WHERE 
    @Param1=0 OR 
    (t1.Col2 in 
     (SELECT t2.Col4 
      FROM 
       Table2 t2 
      WHERE 
       t2.Col1 = t1.Col1 AND 
       t2.Col2 = 'AAA' AND 
       t2.t3 <> 0) 
    ) 

這個查詢執行時間很長的SQL語句。

但是,如果我將@Param1替換爲1,比查詢執行時間大約2秒鐘。

任何信息如何解決這個問題將不勝感激。

+1

請張貼XML版本的實際執行計劃。 –

回答

1

那麼,解釋似乎很簡單。對於您當前的情況,由於@Param1=0爲假(您之前將參數設置爲1),因此需要評估您的第二個條件,其中包含子查詢並可能需要很長時間。如果您將第一個篩選器更改爲@Param1=1,那麼您說這是真的,並且不需要評估第二個篩選器,因此可以使查詢更快。

0

您似乎將優化器與您的OR語句混淆。如果你刪除它,你會發現它產生的SELECT語句兩個不同的執行計劃 - 一個帶有過濾器,以及其他沒有:

DECLARE @Param1 BIT 
SET @Param1 = 1 

if @Param1=0 
begin 
    SELECT 
     t1.Col1, 
     t1.Col2 
    FROM 
     Table1 t1 
end 
else 
begin 
    SELECT 
     t1.Col1, 
     t1.Col2 
    FROM 
     Table1 t1 
    WHERE 
     (t1.Col2 in 
      (SELECT t2.Col4 
       FROM 
        Table2 t2 
       WHERE 
        t2.Col1 = t1.Col1 AND 
        t2.Col2 = 'AAA' AND 
        t2.t3 <> 0) 
     ) 
end 
0

這通常被稱爲N + 1的問題。
你正在做一個表1中的選擇,對於每條記錄你會發現你會在表2中尋找一些東西。
通過設置你的@Param1爲一個永遠不會在你的選擇中找到的值,sql引擎將跳過子查詢。
要避免此行爲,可以使用JOIN語句將兩個表連接在一起,然後用where語句過濾結果。 join語句會比單個子查詢慢一點,因爲你將2個表匹配到eachother,但是因爲你只需要執行一次連接(比N次),你將獲得顯着的性能提升。
示例代碼:

DECLARE @Param1 BIT 
SET @Param1 = 1 

SELECT t1.Col1,t1.Col2 
FROM Table1 t1 
INNER JOIN Table2 t2 on t1.Col1 = t2.Col1 
WHERE @Param1=0 
OR t2.Col2 = 'AAA' 
AND t2.t3 <> 0