2

您好,感谢您的关注。

首先是关于这个问题的一些背景:

我有一个内联表函数,它在我开发的在 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))
4

1 回答 1

1

临时添加一些日志记录以验证实际导致超时问题的原因。您可以在您的应用程序和存储过程本身中执行此操作。让该过程在执行时将当前时间戳和用于调用该过程的参数写入日志表。还将日志记录添加到您的应用程序。然后,如果有某些参数导致问题或问题是否完全存在于过程中,您将能够确定何时发生特定超时。

一般来说,用户定义的函数不是一个好主意,尽管我的理解是表内联函数比其他一些函数更好。它增加了很多开销,优化器无法与 UDF 一起正常工作。

于 2012-06-23T17:40:11.287 回答