【发布时间】:2015-01-26 21:50:23
【问题描述】:
我发现我们在应用程序中使用的一个存储过程存在性能问题。
这是一个非常大的存储过程,我已将其缩小到我看到性能问题的部分。
它在 where 子句中(复制如下)。查询估计计划显示这部分大约占80%。
逻辑是@AssignedToIds和@AssignedToRoleIds可以为null,如果是null,我们就拉取所有记录。
临时表可以有多行。非常感谢您对提高性能的任何帮助。
#AssignedTo 和 #AssignedToRole 是临时表。
#AssignedTo在表中只有一个值,#AssignedToRole为空
SQL:-
SELECT DISTINCT TOP 2000 t.Member_Party_PartyId AS Member_Party_PartyId
FROM Task t
WHERE t.IsDeleted = 0
AND (
t.DueDate >= @DueStart
OR @DueStart IS NULL
)
AND (
t.DueDate <= @DueEnd
OR @DueEnd IS NULL
)
AND (
(
@FilterType = 'MyPatients'
AND t.AssignedUserId = @UserId
)
OR @FilterType != 'MyPatients'
)
AND (@FilterType != 'MyRole')
AND (
(
@FilterType = 'MyGroup'
AND t.AssignedUserId IN (
SELECT PartyId
FROM #OrgMembers
)
)
OR @FilterType != 'MyGroup'
)
AND (
(
@FilterType = 'Custom'
AND vpad.Provider IN (
SELECT PartyId
FROM #OrgMembers
)
)
OR @FilterType != 'Custom'
)
AND (
(
@ActiveCase = 1
AND cases.CaseId IS NOT NULL
)
OR @ActiveCase = 0
)
AND (
t.TaskStatusId IN (
SELECT TaskStatusId
FROM #TaskStatus
)
)
AND (
t.TaskCategoryId IN (
SELECT TaskCategoryId
FROM #TaskCategory
)
OR @TaskCategoryIds IS NULL
)
AND (
t.TaskPriorityId IN (
SELECT TaskPriorityId
FROM #TaskPriority
)
OR @TaskPriorityIds IS NULL
)
AND (
rm.RegistryId IN (
SELECT RegistryId
FROM #Registry
)
OR @RegistryIds IS NULL
)
AND (
(
fg.CareMeasureId IN (
SELECT CareMeasureId
FROM #CareMeasure
)
AND exclusion.MemberId IS NULL
)
OR @CareMeasureIds IS NULL
)
AND (
vpad.OrganizationId IN (
SELECT OrganizationId
FROM #Organization
)
OR (
SELECT count(OrganizationId)
FROM #Organization
) = 0
)
AND (
vpad.Provider IN (
SELECT ProviderId
FROM #Provider
)
OR @ProviderIds IS NULL
)
AND (
cases.CaseTypeId IN (
SELECT CaseTypeId
FROM #CaseType
)
OR @CaseIds IS NULL
)
AND
--(case when @AssignedToIds Is Not Null And then t.AssignedUserId in (select AssignedToId from #AssignedTo))
(
(
t.AssignedUserId IN (
SELECT AssignedToId
FROM #AssignedTo
)
OR (
@AssignedToIds IS NULL
AND @AssignedToRoleIds IS NULL
)
)
OR (
t.AssignedRoleId IN (
SELECT AssignedRoleId
FROM #AssignedToRole
)
OR (
@AssignedToRoleIds IS NULL
AND @AssignedToIds IS NULL
)
)
)
AND (
vpad.OrganizationId IN (
SELECT OrganizationId
FROM #UserOrgs
)
OR (
(
SELECT count(OrganizationId)
FROM #UserOrgs
) = 0
)
OR (@RoleType <> 'Manager')
)
AND (
(
mhp.MemberHealthPlanTypeId IN (
SELECT HealthPlanId
FROM #HealthPlan
)
AND hpds.HierarchyOrder IS NOT NULL
)
OR @HealthPlanIds IS NULL
)
OPTION (RECOMPILE);
【问题讨论】:
-
为什么选择子选择?为什么不加入反对他们呢?
-
无法加入。这些是条件连接。如果变量 --@--AssignedToIds 或 --@--AssignedToRoleIds 有值,我只需要加入临时表。
-
您有前 x 行,但没有排序依据。如果没有 order by,您将无法知道将返回哪些行。
-
看来必须有一种更简洁的方式来写这个。通常我不推荐动态 SQL,但在这种情况下可能值得研究一下?
-
谢谢。如果我没有从论坛中得到任何其他想法,我会尝试一下。
标签: sql sql-server performance tsql