您好,感谢您的关注。
首先是关于这个问题的一些背景:
我有一个内联表函数,它在我开发的在 IIS7 上运行的 ASP.net 应用程序中无处不在。它是 30 个或更多存储过程的基础,所有这些过程通常会在最多 200 毫秒内处理(足够快)。应用程序始终对所有数据库连接使用相同的连接字符串。该函数本身最多运行约 10 毫秒。
有时,对调用使用该函数的存储过程的页面的调用将导致 15 秒后超时。此超时适用于该页面的所有用户,但其他也有使用此功能的存储过程的页面在此发生时仍然可以正常执行,这表明它是一个特定的存储过程有问题。但是,这发生在多个页面上,表明它是多个存储过程或函数本身。
即使 Web 应用程序发生超时,从管理工作室会话使用不同的用户凭据在页面上运行任何(或所有)存储过程的时间都小于 200 毫秒。
在函数上运行 sp_recompile 将始终从任何登录凭据中“清除”超时。
因为这是应用程序的关键部分,所以 sp_recompile 会尽快运行,并且几乎没有时间用于调试。此外,我从来没有能够随意重新创建超时。
我尝试对内联表函数进行大量研究,但没有发现任何表明这是它们的常见问题,因此应该避免使用它们。
问题:
这些超时是否可能是由使用该函数引起的,或者它们是否保证是依赖它的存储过程的问题?换句话说,重构存储过程以使用视图或封装适当的内联逻辑是否有任何好处?
我的猜测是它只是存储过程,我可能会通过添加优化未知,在适当的地方重新编译选项或本地化参数来解决这个问题,但老实说,我更愿意找到一个适用于底层的解决方案功能,以便我可以在单个位置应用修复。
功能:
CREATE FUNCTION [dbo].[fn_ObjectIDs] (
@DateFrom AS DATETIME = NULL
,@DateTo AS DATETIME = NULL
,@Region AS INT = NULL
,@FamilyID AS INT = NULL
,@ParentID AS INT = NULL
,@ChildID AS INT = NULL
) RETURNS TABLE AS
RETURN
SELECT DISTINCT
obj.ID AS IDs
FROM tblObjects obj WITH (NOLOCK)
INNER JOIN tblFamily fam WITH (NOLOCK)
ON obj.famID = fam.famID
LEFT JOIN tblCountry cntry WITH (NOLOCK)
ON (@Region IS NOT NULL) AND (fam.countryId = cntry.countryId)
LEFT JOIN tblParent parent WITH (NOLOCK)
ON (@ParentID IS NOT NULL) AND (obj.ID = parent.objectID)
LEFT JOIN tblChild child WITH (NOLOCK)
ON (@ChildID IS NOT NULL) AND (obj.ID = child.objectID)
WHERE
obj.Visible = 1
AND obj.statusID IN (3,4,6,8)
AND ((@DateFrom IS NULL) OR (obj.CreatedDate >= @DateFrom))
AND ((@DateTo IS NULL) OR (obj.CreatedDate <= @DateTo))
AND ((@Region IS NULL) OR (cntry.regionID = @Region))
AND ((@FamilyID IS NULL) OR (obj.famID = @FamilyID))
AND ((@ParentID IS NULL) OR (parent.parentID = @ParentID))
AND ((@ChildID IS NULL) OR (child.childID = @ChildID))