2015-10-28 49 views
0

我是性能調優存儲過程和SQL Enlight拋出一個高門檻,猜測是因爲許多自聯接。有沒有另一種方法來重寫自連接?是否有替代重寫自連接?

這是我使用的代碼。

在此先感謝。

SELECT x.ClientName 
    ,x.Category 
    ,x.vchSSNumber 
    ,x.dtDateOfBirth 
    ,x.CYC0 
    ,x.Total0 
    ,Limit0 = CASE 
     WHEN x.category = 'IRA' 
      THEN i0.mLimit 
     WHEN x.category = 'Simple' 
      THEN s0.mLimit 
     ELSE NULL 
     END 
    ,Balance0 = CASE 
     WHEN x.category = 'IRA' 
      THEN CASE 
        WHEN i0.mLimit > 0 
         THEN i0.mLimit - x.Total0 
        END 
     WHEN x.category = 'Simple' 
      THEN CASE 
        WHEN s0.mLimit > 0 
         THEN s0.mLimit - x.Total0 
        END 
     ELSE NULL 
     END 
    ,x.CYC1 
    ,x.PYC1 
    ,x.Total1 
    ,i1.mLimit AS Limit1 
    ,Balance1 = CASE 
     WHEN i1.mLimit > 0 
      THEN i1.mLimit - x.Total1 
     END 
    ,x.CYC2 
    ,x.PYC2 
    ,x.Total2 
    ,i2.mLimit AS Limit2 
    ,Balance2 = CASE 
     WHEN i2.mLimit > 2 
      THEN i2.mLimit - x.Total2 
     END 
    ,Over70AndHalf = CASE 
     WHEN x.dtDateOfBirth < @year70 
      THEN 1 
     ELSE 0 
     END 
FROM ClientInfo x 
--Only get contribution limits for IRA Category. Have to get for each year 
--IF DOB is NULL, Assume it is today. This makes them under 50 yrs old 
LEFT JOIN dbo.IRAContributionLimits i0 WITH (NOLOCK) ON @year0 - DATEPART(yy, ISNULL(x.dtDateOfBirth, @date)) BETWEEN i0.iMinAge 
     AND i0.iMaxAge 
    AND i0.iYear = @year0 
    AND i0.vchCategory = x.category 
    AND x.category = 'IRA' 
LEFT JOIN dbo.IRAContributionLimits i1 WITH (NOLOCK) ON @year1 - DATEPART(yy, ISNULL(x.dtDateOfBirth, @date)) BETWEEN i1.iMinAge 
     AND i1.iMaxAge 
    AND i1.iYear = @year1 
    AND i1.vchCategory = x.category 
    AND x.category = 'IRA' 
LEFT JOIN dbo.IRAContributionLimits i2 WITH (NOLOCK) ON @year2 - DATEPART(yy, ISNULL(x.dtDateOfBirth, @date)) BETWEEN i2.iMinAge 
     AND i2.iMaxAge 
    AND i2.iYear = @year2 
    AND i2.vchCategory = x.category 
    AND x.category = 'IRA' 
LEFT JOIN dbo.IRAContributionLimits s0 WITH (NOLOCK) ON @year0 - DATEPART(yy, ISNULL(x.dtDateOfBirth, @date)) BETWEEN s0.iMinAge 
     AND s0.iMaxAge 
    AND s0.iYear = @year0 
    AND s0.vchCategory = x.category 
    AND x.category = 'Simple' 
ORDER BY x.ClientName 
    ,x.category 
    ,x.vchSSNumber; 
+1

也許你可以離開最後的連接,在'Simple'上搜索,你可以在第一個左連接上添加例如:x.category IN('IRA','Simple'),僅當dbo.IRAContributionLimits i0不能包含數據都爲 – Thomas

回答

3

根據我的經驗,自連接不一定會導致性能問題。

看着你的查詢,或任何帶有性能問題的查詢,我看第一個地方就是你的索引。

您的dbo.IRAContributionLimits表有關於iMinAgeiMaxAge,iYearvchCategory的索引嗎?

請問您的ClientInfo表有和category的索引嗎?

+0

嗨奧利維爾,性能不是這個存儲過程的問題,特別是它的複雜性,我所關心的。表'dbo.IRAContributionLimits'只有132行,所以不需要索引,clientInfo是一個數據來自臨時表的cte。 – JVM

+0

我已經看到比這更復雜的存儲過程。 –

+0

正確,但我們的代碼標準只允許存儲過程中的一定數量的複雜性。一旦我們跨越了一定的門檻,它強烈推薦做不同的事情或至少嘗試。 – JVM