2015-08-13 90 views
0

試圖調試存儲的proc以找出它永不結束的原因(等待> 2min)。 proc有3個左連接,然後在底部是一個ISNULL,它檢查一個數據庫的值爲null,然後用第二個數據庫的值替換它。我發現問題的方式是註釋連接和子句,然後慢慢地添加子句中的連接。在添加最後一個子句後,它開始加載時間過長。 我的問題是,有沒有辦法解決這個不涉及索引?如果可能的話,你能否解釋爲什麼這會導致大的加載時間?SQL存儲過程;使用ISNULL(db1.value,db2.value)性能問題

FROM X x WITH (NOLOCK) 
    LEFT JOIN A a WITH (NOLOCK) 
      ON a.a1 = x.x1 
    LEFT JOIN B b WITH (NOLOCK) 
      ON b.b1 = a.a1 AND LEFT(a.a2, 2) = '--' AND a.a2 NOT IN ('---') 
    LEFT JOIN C c WITH (NOLOCK) 
      ON c.c1 = a.a1 AND LEFT(a.a2, 2) <> '--' AND a.a2 NOT IN ('---', '---', '--', '--', '--') 
    WHERE ISNULL(x.x3, 0) <> 1  
    AND CASE 
      WHEN x.x2 IN ('--', '---', '---') THEN '----' 
      WHEN x.x2 IN ('---') THEN x.x2 
      END = @2 
    AND ISNULL(b.b2, c.c2 + c.c3) LIKE @3 

注:我用虛擬變量替換了大多數值,但它們是一致的。

感謝您的任何幫助。

+0

因此,雖然'ISNULL(b.b2,c.c2​​ + c.c3)LIKE @ 3'這一行表現很好嗎?或性能受損於'ISNULL(x.x3,0)<> 1'行?這個主題和問題意味着你的where子句中的最後一個,但不知道......邏輯上,如果b.b2爲空...... c.c2 + c.c3也可以爲null。添加空值會導致null,但隨後比較@ 3這樣的空值會有問題。或者'ISNULL(b.b2,coalesce(c.c2,'')+ coalesce(c.c3,''))'如果字符串或'ISNULL(b.b2,coalesce(c.c2,0)+ coalesce c.c3))'如果c c.c2和c.c3是數字。 – xQbert

+0

對不起, b.b2,c.c2​​,c.c3是字符串。是的問題正好發生在ISNULL(b.b2 ....)b2將爲空或c2和c3將爲空,但不是b2和c2/c3。另外@ 3是一個VARCHAR(15),如果有幫助的話。謝謝你的回答。 – NSII

+0

你可以舉一個例子,說明@ 3和c.c2和c.c3中什麼時候會'實現'我很好奇,如果類似'%'或SQL想在執行之前想要什麼。此外,SQL Server執行計劃的屏幕截圖可能有助於隔離瓶頸。 – xQbert

回答

1

的問題是所謂的,SARGability,SQL Server不能當你在WHERE子句或聯接使用的功能使用索引。

你可以只用x.x3 <> 1替換此ISNULL(x.x3, 0) <> 1因爲空值不匹配進不去。

對於第二ISNULL:ISNULL(b.b2, c.c2 + c.c3) LIKE @3,如果知道會在這種情況下,C2的東西,你可以與工會或工會代替所有的東西是這樣的:

select ... 
    WHERE ISNULL(x.x3, 0) <> 1  
    AND CASE 
      WHEN x.x2 IN ('--', '---', '---') THEN '----' 
      WHEN x.x2 IN ('---') THEN x.x2 
      END = @2 
    AND b.b2 LIKE @3 

union all 

select ... 
    WHERE ISNULL(x.x3, 0) <> 1  
    AND CASE 
      WHEN x.x2 IN ('--', '---', '---') THEN '----' 
      WHEN x.x2 IN ('---') THEN x.x2 
      END = @2 
    AND b.b2 is NULL and c.c2 = @startof3 and c.c3 like @endof3 

此外,聯接可能會執行得更好如果您將LEFT(a.a2, 2) = '--'更改爲a.a2 like '--%',因爲這是SARGable。