需要一些优化存储过程的帮助

时间:2012-02-10 14:05:56

标签: sql-server-2008 stored-procedures user-defined-functions scalar

我有一个存储过程,它正在构建动态sql查询,然后通过exec(@sql)运行它。

存储过程正在加入大约12个表。事实上,它的运行速度相对较快。但后来我需要添加一个额外的字段。为此,我创建了一个标量函数,如下所示:

SELECT @weight = @weight +COUNT(*) FROM dbo.UserPDMedication WHERE UserID = @userid
SELECT @weight = @weight +COUNT(*) FROM dbo.[User] WHERE UserID = @userid AND HoehnYarhID IS NOT null
SELECT @weight = @weight +COUNT(*) FROM dbo.[User] WHERE UserID = @userid AND DateOfBirth IS NOT NULL
SELECT @weight = @weight +COUNT(*) FROM dbo.[User] WHERE UserID = @userid AND GenderID IS NOT NULL
SELECT @weight = @weight +COUNT(*) FROM dbo.[User] WHERE UserID = @userid AND DateDiagnosed IS NOT null

它基本上只是一个函数,它将根据用户填写的问题返回一个int。因此,对于存储过程中的每个用户,都会调用此函数。存储过程如下所示:

    SELECT DISTINCT u.UserID, u.Healthy, u.DateOfBirth, u.City, st.StateCode AS State, u.GenderID, g.Gender, u.Latitude, u.Longitude, u.PDConditionID, u.Zip, u.Distance,
    (SELECT TOP 1 EmailID FROM Messages m WHERE TrialID = ' + @trialID + ' AND ToUserID = u.userid AND LocationID = ' + @locationID + ') AS MessageID, dbo.UserWeightedValue(u.UserID) as wt
FROM [User] u
    INNER JOIN aspnet_UsersInRoles uir ON u.AspnetUserID = uir.UserId
    INNER JOIN aspnet_Roles r ON uir.RoleId = r.RoleId
    FULL JOIN UserHealthCondition uhc ON u.UserID = uhc.UserID
    FULL JOIN UserMotorSymptom ums ON u.UserID = ums.UserID
    FULL JOIN UserNonMotorSymptom unms ON u.UserID = unms.UserID
    FULL JOIN UserPDMedication updm ON u.UserID = updm.UserID
    FULL JOIN UserPDTreatment updt ON u.UserID = updt.UserID
    FULL JOIN UserSupplement us ON u.UserID = us.UserID
    FULL JOIN UserPDGeneticMarker updgm ON u.UserID = updgm.UserID
    FULL JOIN UserFamilyMember ufm ON u.UserID = ufm.UserID
    FULL JOIN State st ON u.StateID = st.ID
    FULL JOIN Gender g ON u.GenderID = g.ID
WHERE u.UserID IS NOT NULL

(我删除了一些块试图保持这个简短)。此get作为存储过程中的动态字符串执行。关于如何优化这一点以加快速度的任何提示?

由于

编辑:我在这里使用了一些建议。虽然我将多个select语句组合成2个语句,但我保持了我的功能。然后我接受了原始的存储过程并将select更改为选择## temp。然后我在临时表上运行我的函数。执行时间下降到3-4秒。我想我将不得不赞扬这个问题的授予,因为他指出了明显的让我走上正确的道路。但是谢谢大家。

3 个答案:

答案 0 :(得分:1)

如果UserID是表User的主键,则无需为用户填写的问题执行一个SELECT,您可以将其包装在一个SELECT中{1}}:

SELECT @weight = @weight + COUNT(HoehnYarhID) + COUNT(DateOfBirth) + COUNT(GenderID) + COUNT(DateDiagnosed)
FROM dbo.[User] 
WHERE UserID = @userid 

答案 1 :(得分:1)

DISTINCT绝对会导致性能受到影响,因为它会进行聚合。你真的需要它吗?通常,当您看到DISTINCT时,它表明数据或结构问题正在被消除重复的能力所掩盖,结构应该自行消除重复。

之后,我会将其作为JOIN移动,而不是SELECT列表中的相关查询。这不是一个肯定的胜利,但优化者通常能够更好地将其纳入计划中。

根据您所呈现的复杂性,我还会查看执行计划。要检查的第一件事是,你有一个完整的优化或超时。如果它超时,那么你正在处理一个最好的猜测,而不是一个完全计算的“足够好”的计划。如果是这样,你需要看看简化这个查询。如果您有足够好的计划,请查看其中的瓶颈所在。

答案 2 :(得分:0)

将标量值函数转换为内联表值函数。

相关问题