缓冲区缓存清理时出现“超时已过期”错误

时间:2010-06-01 15:25:53

标签: c# .net winforms linq sql-server-2005

我将首先总结我的问题,然后提供大量细节以及我已经尝试过的内容。

要点:

我有一个内部winform应用程序,它使用Linq 2 Sql连接到本地SQL Express数据库。每个用户都有自己的数据库,并且数据库通过合并复制与中央数据库保持同步。所有数据库都是SQL 2005(sp2or3)。我们现在使用此应用已超过5个月,但最近我们的用户获得了Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

详细说明:

奇怪的是,他们在两个不同的位置( 2个不同的LINQ方法)得到它,并且只在他们第一次在给定时间段内开火( ~5mins

一个LINQ方法是拉出与FK ID匹配的所有记录,然后对它们进行操作以形成TreeView的Heirarchy视图。第二个是拉出与FK ID匹配的所有记录并将它们转储到DataGridView中。我能找到的唯一与2相同的东西是第一个是IEnumerable而第二个是从IQueryable转换自己 - > IEnumerable - >数据表...

我查看了Profiler中的查询,他们似乎“正常”。它们并不是非常复杂的查询。他们只从一张桌子上撤回了10到90条记录。

任何想法,建议,提示都会受到高度赞赏。我在这方面已经结束了......


public IList<CaseNoteTreeItem> GetTreeViewDataAsList(int personID)
{
    var myContext = MatrixDataContext.Create();

    var caseNotesTree =
        from cn in myContext.tblCaseNotes
        where cn.PersonID == personID
        orderby cn.ContactDate descending,
            cn.InsertDate descending
        select new CaseNoteTreeItem
        {
            CaseNoteID = cn.CaseNoteID,
            NoteContactDate = Convert.ToDateTime(cn.ContactDate).
                ToShortDateString(),
            ParentNoteID = cn.ParentNote,
            InsertUser = cn.InsertUser,
            ContactDetailsPreview = cn.ContactDetails.Substring(0, 75)
        };

    return caseNotesTree.ToList<CaseNoteTreeItem>();            
}

和这一个

public static DataTable GetAllCNotes(int personID)
{
    using (var context = MatrixDataContext.Create())
    {
        var caseNotes =
            from cn in context.tblCaseNotes
            where cn.PersonID == personID
            orderby cn.ContactDate
            select new
            {
                cn.ContactDate,
                cn.ContactDetails,
                cn.TimeSpentUnits,
                cn.IsCaseLog,
                cn.IsPreEnrollment,
                cn.PresentAtContact,
                cn.InsertDate,
                cn.InsertUser,
                cn.CaseNoteID,
                cn.ParentNote
            };

        return caseNotes.ToList().CopyLinqToDataTable();
    }
}

编辑以显示生成的SQL

这是GetTreeViewAsList(int personID)

SELECT [t0].[CaseNoteID], [t0].[ParentNote] AS [ParentNoteID], CONVERT(DateTime,[t0].[ContactDate]) AS [value], [t0].[InsertUser], SUBSTRING([t0].[ContactDetails], 0 + 1, 75) AS [ContactDetailsPreview]
FROM [dbo].[tblCaseNotes] AS [t0]
WHERE [t0].[PersonID] = 123456
ORDER BY [t0].[ContactDate] DESC, [t0].[InsertDate] DESC

这是GetALlCaseNotes(int personID)

SELECT [t0].[ContactDate], [t0].[ContactDetails], [t0].[TimeSpentUnits], [t0].[IsCaseLog], [t0].[IsPreEnrollment], [t0].[PresentAtContact], [t0].[InsertDate], [t0].[InsertUser], [t0].[CaseNoteID], [t0].[ParentNote]
FROM [dbo].[tblCaseNotes] AS [t0]
WHERE [t0].[PersonID] = 123456
ORDER BY [t0].[ContactDate]

2 个答案:

答案 0 :(得分:1)

这有点远,但问题可能不是性能问题,而是连接问题。当您的SQL Server配置为使用命名管道而不是默认协议时,.NET SqlClient可能需要很长时间才能建立连接,因为它尝试使用默认协议顺序进行连接。

您可以阅读更多相关信息,here.

祝你好运。

答案 1 :(得分:1)

PersonId上缺少索引意味着两个问题查询都需要进行全表扫描。当数据不在缓冲区中时,这意味着很多I / O,这解释了为什么你注意到它,特别是它们在特定时间段内第一次发射时。

添加以下索引应该解决它。

CREATE NONCLUSTERED INDEX ix_tblCaseNotes_PersonID ON tblCaseNotes (PersonID)