性能瓶颈 - Linq to SQL或数据库 - 我该怎么说?

时间:2010-02-13 12:38:41

标签: sql performance linq-to-sql sql-server-2008

我目前正试图通过我的报告网站使用linq to sql和sql server express 2008数据库来提高性能。 我发现,由于我现在在更“丑陋”的表格中接近了一百万行,因此性能成为一个真正的问题,一个报告特别需要3分钟才能生成。

基本上,我有一个循环,对于每个用户,它会命中数据库并抓取它们上的数据集合。然后以各种方式查询此数据(并根据需要加载更多行),直到我有一个很好的小摘要对象,我可以触发到一组silverlight图表。使用延迟加载,报告从大约8个链接表中提取数据。

问题是我不知道现在的瓶颈在哪里以及如何提高性能。由于某些限制,我被迫对所涉及的表中的许多主键使用uniqueidentifiers - 这可能是一个问题吗?

基本上,我需要花时间提高性能但是没有足够的数据库或linq到sql。无论如何我能看到瓶颈在哪里?

因为我正在运行表达我无法访问探查器。我正在考虑将我的查询重写为已编译的linq到sql,但担心数据库可能是罪魁祸首。

我理解这个问题有点开放,如果不了解更多关于我的设置(数据库架构等)的话,很难回答,但是如何找出瓶颈所在的任何建议都会受到更多的赞赏!

由于

更新: 感谢所有伟大的建议人员,以及一些很棒的工具链接。

感兴趣的人更新 通过调整linq,我无法更快地查询。问题似乎是我的大部分数据库访问代码都是在循环中进行的。我看不到它的方法。基本上我通过查看大量用户数据来构建报告 - 因此循环。预先拉出所有记录似乎有点疯狂 - 800,000 +行。我的直觉是,有一个更好的方法,但它对我来说是一个技术上的飞跃!

但是,在其中一个表中为其中一个外键添加另一个索引会提高性能,所以现在生成报告需要20秒而不是3分钟!

3 个答案:

答案 0 :(得分:2)

我使用了2个工具,LinqPad和Visual Studio Debugger。首先,check out LinqPad,即使免费版本也非常强大,显示执行时间,生成的SQL,您可以使用它来运行任何代码片段...... 它非常有用

其次,你可以使用Visual Studio调试器,这是我们在DataContext 上使用的东西(注意:只在调试中使用它,这是性能损失,在调试之外完全没必要)

#if DEBUG
  private readonly Stopwatch Watch = new Stopwatch();

  private static void Connection_StateChange(object sender, StateChangeEventArgs e)
  {
    if (e.OriginalState == ConnectionState.Closed && e.CurrentState == ConnectionState.Open) 
    {
      Current.Watch.Start();
    }
    else if (e.OriginalState == ConnectionState.Open && e.CurrentState == ConnectionState.Closed)
    {
      Current.Watch.Stop();

      string msg = string.Format("SQL took {0}ms", Current.Watch.ElapsedMilliseconds);
      Trace.WriteLine(msg);
    }
  }
#endif

private static DataContext New
{
  get
  {
    var dc = new DataContext(ConnectionString);
#if DEBUG
    if (Debugger.IsAttached)
    {
      dc.Connection.StateChange += Connection_StateChange;
      dc.Log = new DebugWriter();
    }
#endif
    return dc;
  }
}

在调试版本中,当操作完成每个上下文时,我们会看到调试窗口中的时间戳和它运行的SQL。 The DebugWriter class you see can be found here (图片来源:Kris Vandermotten)。我们可以快速查看查询是否需要一段时间。要使用它,我们只需通过以下方式启动DataContext:

var DB = DataContext.New;

(由于我们不使用SQL服务器,分析器不适合我,这个答案只是为了给你一些对我非常有用的选择)

答案 1 :(得分:2)

我使用了这个优秀的工具:Linq2Sql profiler。它适用于应用程序端,因此不需要数据库服务器分析功能。

您必须向应用程序添加一行初始化代码,然后在单独的桌面应用程序分析器中显示每个LINQ查询的SQL查询,其中包含执行它的确切代码行(cs或aspx),数据库时间和应用程序时间执行甚至检测到一些常见的性能问题,如n + 1查询(迭代执行的查询)或无界数据集。您必须为此付费,但也可以使用试用版。

答案 2 :(得分:2)

当您使用没有Profiler的SQL Express时,您可以下载免费的第三方分析器here。我在运行SQL Express时使用过它。这将允许您跟踪数据库中正在发生的事情。

此外,您可以查询动态管理视图以查看代价高昂的查询: 例如占用时间最多的十大查询

SELECT TOP 10 t.text, q.*, p.query_plan
FROM sys.dm_exec_query_stats q
    CROSS APPLY sys.dm_exec_sql_text(q.sql_handle) t
    CROSS APPLY sys.dm_exec_query_plan (q.plan_handle) AS p
ORDER BY q.total_worker_time DESC