SQL语句调用自定义函数很慢
在一个视图查询中,执行速度很慢,是因为执行调用两个函数导致,
大概查询8000条数据,不调用函数1秒就可以搞定,加上调用的函数,则需要1分50秒左右。
SQL语句如下:
select ea.ExpenseAppId,ea.ExpenseCode,ea.Template,
ea.StatusId,dbo.GetApprovalStatus_Module(ea.statusId,2) as Status,ea.CreateTime,ea.ProjectId,ea.ProgramId,
ea.CreatorId,dbo.GetStaffName(ea.CreatorId) as Creator,ea.ApplicantId,dbo.GetStaffName(ea.ApplicantId) as Applicant,
dbo.f_AppHistoryActApproverIdUserList(ea.ExpenseAppId,2)'ActApproverIdUserList',
dbo.f_AppHistoryOrgApproverIdUserList(ea.ExpenseAppId,2)'OrgApproverIdUserList'
from ExpenseApp ea
where ExpenseAppId in(select distinct(ExpenseAppId) from ApprovalHistory where ExpenseAppId!=0 and TripAppId=0)
函数如下:
ALTER function [dbo].[f_AppHistoryActApproverIdUserList](@id int,@ModuleId int)
returns varchar(1000)
as
begin
declare @r varchar(1000)
set @r=''
select @r=@r+','+ ltrim(str(ActApproverId)) from AppHistory where (StatusId>1 or Actions like 'Approv%' or Actions like 'Reject%') and ModuleId=@ModuleId and OrgApproverId=ActApproverId and ApplicationId=@id
return stuff(@r,1,1,'')+','
end
请问可以怎样优化?
[解决办法]
有自定义函数,还有in, 肯定很慢。建议改用存储过程。
你的函数查询大表肯定会导致你的查询速度大大降低,
[解决办法]
自定义函数的性能确实比较差,能不用的情况尽量不要用。
[解决办法]
查询语句的条件不要用函数,用了肯定慢。
[解决办法]
自定义函数甚至系统函数都容易导致索引无效,所以除非实在没办法,不然没必要用,特别是在on、where中使用。
[解决办法]
你这个函数中还要调用表,如果有8000条数据的话也就是8000次调用啊,这个部分看看能不能优化。 另外这个表不能跟调用这个函数的表连接吗?如果可以避免使用函数性能会好很多
[解决办法]
-- 试试这个
SELECT ea.ExpenseAppId,ea.ExpenseCode,ea.Template,
ea.StatusId,dbo.GetApprovalStatus_Module(ea.statusId,2) as Status,ea.CreateTime,ea.ProjectId,ea.ProgramId,
ea.CreatorId,dbo.GetStaffName(ea.CreatorId) as Creator,ea.ApplicantId,dbo.GetStaffName(ea.ApplicantId) as Applicant,
STUFF(ap.ApproverIdUserList,1,1'') AS ActApproverIdUserList,
STUFF(ap.ApproverIdUserList,1,1,'') AS OrgApproverIdUserList
FROM ExpenseApp ea
CROSS APPLY (
SELECT ','+ LTRIM(str(ActApproverId)) FROM AppHistory WHERE ModuleId=2 and OrgApproverId=ActApproverId and ApplicationId=ea.ExpenseAppId
and (StatusId>1 or Actions like 'Approv%' or Actions like 'Reject%')
FOR XML PATH('')
) ap (ApproverIdUserList)
WHERE ea.ExpenseAppId IN(SELECT DISTINCT (ExpenseAppId) FROM ApprovalHistory WHERE ExpenseAppId!=0 and TripAppId=0)