TSQL IVF 导致 ASP.net 应用程序超时

Posted

技术标签:

【中文标题】TSQL IVF 导致 ASP.net 应用程序超时【英文标题】:TSQL IVF causing timeout in ASP.net application 【发布时间】:2012-05-29 13:01:01 【问题描述】:

您好,感谢您的关注。

首先介绍一下这个问题的背景:

我有一个内联表函数,它在我开发的在 IIS7 上运行的 ASP.net 应用程序中无处不在。它是 30 个或更多存储过程的基础,所有过程通常最多在 200 毫秒内处理(足够快)。应用程序始终对所有数据库连接使用相同的连接字符串。函数本身运行时间最长约为 10 毫秒。

有时,对调用存储过程的页面的调用会在 15 秒后导致超时。此超时适用于该页面的所有用户,但其他也有使用此功能的存储过程的页面在此发生时仍然可以正常执行,这表明它是一个特定的存储过程有问题。但是,这发生在多个页面上,表明它是多个存储过程或函数本身。

使用不同的用户凭据从 Management Studio 会话中运行页面上的任何(或所有)存储过程的时间小于 200 毫秒,即使 Web 应用程序发生超时也是如此。

在函数上运行 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))

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

感谢您的回复。我添加了一些日志记录,结果将问题隔离到一个存储过程中。这导致在***.com/questions/11557635/… 找到一个相关问题。我会尽快回复(道歉),但我不确定您的评论“一般来说用户定义的函数不是一个好主意”。如果函数是内联表函数,我找不到太多支持,而这种担忧是问题的主旨。 我同意你的观点,我没有找到任何支持使用内联表函数是一种不好的做法的证据。我的理解是它们比标量函数更好,但仍然效率低下。在过去的一个月里,我一直在研究和使用它们,我认为使用它们没有任何问题。

以上是关于TSQL IVF 导致 ASP.net 应用程序超时的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET GridView[编辑]列如何超链接

会话超时时创建一个新的 ASP.NET_SessionId

带有参数化超链接的 ASP.NET 引导可切换选项卡

Jquery AJAX ASP.NET IIS 跨域 超简单解决办法

ASP.Net 用户控件悬停导致点击

Asp.Net jQuery $.getJSON 有时会导致整页回发?