Sql 除了重写自联接,还有其他方法吗?

Sql 除了重写自联接,还有其他方法吗?,sql,Sql,我正在对一个存储过程进行性能调优,SQL Enlight抛出了一个很高的阈值,猜测是因为有很多自连接。是否有其他方法重写自联接 这是我正在使用的代码 提前谢谢 SELECT x.ClientName ,x.Category ,x.vchSSNumber ,x.dtDateOfBirth ,x.CYC0 ,x.Total0 ,Limit0 = CASE WHEN x.category = 'IRA'

我正在对一个存储过程进行性能调优,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;
选择x.ClientName
,x.类别
,x.vchs编号
,x.dtDateOfBirth
,x.CYC0
,x.0
,Limit0=CASE
当x.category='IRA'
然后是i0.mLimit
当x.category='Simple'
然后s0.mLimit
否则无效
结束
,余额0=案例
当x.category='IRA'
那么情况呢
当i0.mLimit>0时
然后i0.mLimit-x.Total0
结束
当x.category='Simple'
那么情况呢
当s0.mLimit>0时
然后s0.mLimit-x.Total0
结束
否则无效
结束
,x.CYC1
,x.PYC1
,x.Total1
,i1.mLimit AS Limit1
,余额1=案例
当i1.mLimit>0时
然后是i1.mLimit-x.Total1
结束
,x.CYC2
,x.PYC2
,x.Total2
,i2.mLimit AS Limit2
,余额2=案例
当i2.mLimit>2时
然后是i2.mLimit-x.Total2
结束
,70岁以上,一半=病例
当x.dtDateOfBirth<@year70
那么1
其他0
结束
来自ClientInfo x
--仅获取IRA类别的供款限额。每年都要拿到
--如果DOB为NULL,则假设它是今天。这使得他们不到50岁
在i0.imanage之间的@year0-DATEPART(yy,ISNULL(x.dtDateOfBirth,@date))上使用(NOLOCK)左连接dbo.IRAContributionLimits i0
和i0.iMaxAge
i0.iYear=@year0
i0.vchCategory=x.category
和x.category='IRA'
在i1.imanage之间的@year1-DATEPART(yy,ISNULL(x.dtDateOfBirth,@date))上用(NOLOCK)左键连接dbo.iragributionlimits i1
和i1.iMaxAge
和i1.iYear=@year1
和i1.vchCategory=x.category
和x.category='IRA'
在i2.imanage之间的@year2-DATEPART(yy,ISNULL(x.dtDateOfBirth,@date))上用(NOLOCK)左键连接dbo.iragributionlimits i2
和i2.iMaxAge
i2.iYear=@year2
i2.vchCategory=x.category
和x.category='IRA'
在s0.imanage之间的@year0-DATEPART(yy,ISNULL(x.dtDateOfBirth,@date))上用(NOLOCK)左键连接dbo.irapributionlimits s0
和s0.iMaxAge
s0.iYear=@year0
和s0.vchCategory=x.category
和x.category='Simple'
按x.ClientName订购
,x.类别
,x.vchSSNumber;

根据我的经验,自连接不一定会导致性能问题

查看您的查询,或者任何有性能问题的查询,我首先要查看的是您的索引

您的
dbo.IRAContributionLimits
表是否在
imanage
iMaxAge
iYear
vchCategory
上有索引


您的
ClientInfo
表是否在
dtDateOfBirth
类别上有索引?

根据我的经验,自联接不一定会导致性能问题

查看您的查询,或者任何有性能问题的查询,我首先要查看的是您的索引

您的
dbo.IRAContributionLimits
表是否在
imanage
iMaxAge
iYear
vchCategory
上有索引


您的
ClientInfo
表是否在
dtDateOfBirth
类别上有索引?

根据我的经验,自联接不一定会导致性能问题

查看您的查询,或者任何有性能问题的查询,我首先要查看的是您的索引

您的
dbo.IRAContributionLimits
表是否在
imanage
iMaxAge
iYear
vchCategory
上有索引


您的
ClientInfo
表是否在
dtDateOfBirth
类别上有索引?

根据我的经验,自联接不一定会导致性能问题

查看您的查询,或者任何有性能问题的查询,我首先要查看的是您的索引

您的
dbo.IRAContributionLimits
表是否在
imanage
iMaxAge
iYear
vchCategory
上有索引


您的
ClientInfo
表是否在
dtDateOfBirth
category
上有索引?

也许您可以离开最后一个连接,在那里搜索“Simple”,您可以将其添加到左一个连接,例如:x.category IN('IRA','Simple'),只有当dbo.iragributionlimits i0不能包含这两个的数据时,您才可以离开最后一个连接,在“Simple”上搜索,您可以将其添加到第一个左连接,例如:x.category IN('IRA','Simple'),只有当dbo.iragributionlimits i0不能包含这两个的数据时,您才可以离开最后一个连接,在“Simple”上搜索,您可以将其添加到第一个左连接中,例如('IRA','Simple')中的x.category,只有当dbo.irapributionlimits i0不能包含这两个的数据时,您才可以离开最后一个连接,在“Simple”上搜索时,您可以将其添加到第一个左连接中,例如('IRA','Simple')中的x.category,只有当dbo.IRAContributionLimits i0不能包含两个Hi Olivier的数据时,性能才不是这个存储过程的问题,特别是我关心的复杂性。表
dbo.IRAContributionLimits
只有132行,因此不需要索引,clientInfo是一个cte,数据来自临时表。我见过比这复杂得多的存储过程。没错,但我们的代码标准只允许存储过程中存在一定程度的复杂性。一旦我们跨过某个门槛,它强烈建议我们做一些不同的事情,或者至少尝试一下。嗨,奥利弗,性能不是一个问题