我将首先总结我的问题,然后提供大量细节以及我已经尝试过的内容。
我有一个内部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]
答案 0 :(得分:1)
这有点远,但问题可能不是性能问题,而是连接问题。当您的SQL Server配置为使用命名管道而不是默认协议时,.NET SqlClient可能需要很长时间才能建立连接,因为它尝试使用默认协议顺序进行连接。
您可以阅读更多相关信息,here.
祝你好运。答案 1 :(得分:1)
PersonId上缺少索引意味着两个问题查询都需要进行全表扫描。当数据不在缓冲区中时,这意味着很多I / O,这解释了为什么你注意到它,特别是它们在特定时间段内第一次发射时。
添加以下索引应该解决它。
CREATE NONCLUSTERED INDEX ix_tblCaseNotes_PersonID ON tblCaseNotes (PersonID)