【问题标题】:LINQ to SQL : Too much CPU Usage: What happens when there are multiple usersLINQ to SQL:过多的 CPU 使用:当有多个用户时会发生什么
【发布时间】:2010-05-01 07:18:24
【问题描述】:

我正在使用 LINQ to SQL 并看到我的 CPU 使用率飙升。请参见下面的屏幕截图。我有三个问题

  • 我可以做些什么来减少这个 CPU 使用率。我已经完成了分析并基本上删除了所有内容。将每个 LINQ to SQL 语句变成编译查询有帮助吗?

  • 我还发现,即使使用已编译的查询,像 ByID() 这样的简单语句在具有 3.25GB RAM 3.17GHz 的服务器上也可能需要 3 毫秒 - 这在功能较弱的计算机上只会变得更慢。还是编译的查询会越用越快?

  • 单个用户的 CPU 使用率(在本地服务器上达到 12-15%)将乘以访问服务器的用户数量 - 当应用程序放在实时服务器上时。即一次 2 个用户意味着 15*2 = 30% CPU 使用率。如果是这种情况,那么我的应用程序一次最多只能有 4-5 个用户。或者 LINQ to SQL .net 不共享一些 CPU 使用率。 alt text http://www.freeimagehosting.net/uploads/5f10e1f694.png

【问题讨论】:

  • 您可以发布您认为是导致问题的查询的 SQL 吗?
  • 您的 SQL Server 是否在同一台机器上?你确定 LINQ to SQL (.NET) 正在吃掉你的 CPU,还是你的 SQL Server?
  • 我目前正在使用以下过程调整使用 L2S 的大型应用程序(非常成功!)启动 SQL Server Profiler 并使用保存到文件的“调整”模板创建跟踪。然后与您的应用程序交互以锻炼慢点。停止跟踪,然后启动数据库引擎优化顾问。您可以加载刚刚创建的跟踪文件并让它建议各种优化。我刚刚根据它的建议创建了 5 个非聚集索引,我的应用比以前快了 90%。

标签: .net sql-server-2005 linq-to-sql cpu


【解决方案1】:

个人资料。轮廓。个人资料。

配置文件以准确找出哪个查询占用的资源最多并提高该查询的性能。您可以使用 DataContext 的 Log 属性来查看 SQL - 请参阅this article。您可以在 SQL Server 中获取查询的查询计划 - 请参阅 this article

改进查询的方法示例:

  • 添加缺失的索引。
  • 重写查询以利用已有的索引。
  • 不要为每个查询获取太多数据 - 使用分页并仅在请求时获取更多行。不要获取不需要的字段。
  • 不要每次查询获取的数据太少 - 不要循环一次获取一行。一次获取多行。

完成此操作后,再次配置文件以检查您是否提高了该查询的性能。如果没有,请重复直到有。

然后再次分析以查看下一个杀手查询是什么并重复该过程直到您的性能可以接受。

您说您已经进行了分析,但您还没有发布任何分析信息,例如查询、查询计划、执行时间、查询频率等。如果没有更多分析信息,我们只能猜测。

【讨论】:

  • 索引是什么? SQL 服务器中的表。 LINQ to SQL 是否甚至关心表上的索引 - 它在这里不存在 social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/…
  • @soldieraman:LINQ to SQL 将查询表达式转换为 SQL。 SQL 服务器根据可用的索引和表的统计信息为这些 SQL 语句创建查询计划。您可以通过将某些内容分配给上下文的 Log 属性来记录发送到数据库的 SQL 语句。
  • LINQ 对数据库索引的参与与任何其他外部实体(最终用户、开发人员、ADO.NET、ODBC 等)相同。如果您已将索引创建为数据库架构的一部分,则 LINQ将使用它们,因为您的数据库已经设置为使用它们。
  • 遗憾的是,花费这么多时间的查询都在已经被索引的主键 id 上。其他2个问题的答案呢。有人吗?
  • @soldieraman:主键查找应该非常快,所以我怀疑您每次查询获取的行数太少或太多 - 请参阅我的第 3 条和第 4 条建议。每个查询你要计算多少行?你每秒运行多少个查询?
【解决方案2】:

我注意到这里的一些应用程序有类似的行为;使用 ANTS Profiler,我们将 CPU 利用率缩小到在 Linq to SQL 代码中。我们发现了几个主要的地方,这成为一个问题:

  1. 复杂的 Linq to SQL 查询。使用多个连接和 where 子句约束等。这些问题是 Linq to SQL 引擎必须将 C# 语句转换为 SQL 语句。我相信,如果相同的代码由相同的 DataContext 调用,我相信默认情况下可以重复使用这种转换,但是如果每次执行都实例化一个新的 DataContext,那么每次都会执行 CPU 密集型转换代码。这可以通过将复杂的 Linq to SQL 查询替换为存储过程或使用预编译的 Linq to SQL 查询 (Here's a blog post showing how to create a compiled query) 来解决。
  2. 基于反射的属性分配。我们发现像DataContext.Orders.FirstOrDefault(o => o.OrderID = orderID) 这样的简单查询可能会占用大量CPU,因为它们使用反射将所有属性设置为查询返回的值。超出这一点,我们还没有对此进行调查;我们已经简单地将一些基于 Linq to SQL 的代码替换为标准 C# 数据访问(例如,SqlCommand、SqlClient),用手写代码将适当的列数据提取到适当的属性中,但仅限于 ANTS 告诉我们最多的地方重要的。进行此更改通常会显着降低 CPU 利用率(例如,将 CPU 利用率从 2000 毫秒降至 39 毫秒)。
  3. 一般的 Linq 性能问题(不特定于 Linq to SQL);虽然与类似的迭代方法相比,编写 Linq 查询确实会导致更多的意图揭示代码,但我们发现有时查询最终会非常低效(通常通过多次迭代集合或构建一个真正不需要的笛卡尔积) .我没有想到任何这样的例子,但 ANTS 也能够帮助定位这些问题(通常为特定的代码行寻找极高的命中数)。这些问题通常可以通过对 Linq 查询进行细微调整(或者在某些情况下用几条语句替换 Linq 查询)来解决。

也许需要注意的是,我们对 Linq to SQL 的使用是基于 GUI 创建的 DBML 文件,因此属性修饰类包含有关列映射等的所有信息。

这正是我们发现的关于 Linq to SQL 的内容;我很想看看其他人的经历。我强烈推荐ANTS Performance Profiler 来确定应用程序中 CPU 利用率的集中位置;请注意,如果高 CPU 利用率是基于 SQL 的(在您的情况下听起来不像),那么 ANTS 可能无济于事(我的其他答案也无济于事:))。

【讨论】:

    【解决方案3】:

    编译的查询不会随着更多的使用而“变得更快”。编译查询的主要好处是无需 LINQ 引擎在每次调用时重复执行翻译过程。

    就 CPU 使用率而言,如果这是您的开发机器,那么很有可能其他东西正在导致如此高的活动。即使这是一个专用的数据库服务器,我强烈建议使用 SQL Profiler 来调查您的 LINQ 查询正在生成哪些语句。它可能需要调整架构、代码或数据库设置,以使使用恢复到更可接受的水平。

    【讨论】:

      【解决方案4】:

      我们最近使用 linq to sql 部署了一个大型电子商务应用程序,并且经历了与您描述的非常相似的 CPU 使用率。

      经过几周的分析和调试跟踪,事实证明,恶棍是运行时查询的 jit 编译。

      我们遍历数据层并将所有查询转换为已编译查询,并且我们的 CPU 使用率立即从恒定的 100% 变为平均 5% 到 20%,在首次编译查询时出现了高达 80% 的峰值。

      【讨论】:

        【解决方案5】:
        1. 是否有可以缓存的常用查询?
        2. 可以重写 linq 查询
        3. 大部分查询处理是在 Web 服务器上还是在 SQL 中完成的?
        4. 您是否在同一个机器上同时运行 SQL 服务器和 Web 服务器?您是否有模拟生产环境的测试环境?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-06-13
          • 1970-01-01
          • 2020-09-12
          • 2011-04-20
          • 1970-01-01
          • 2015-06-19
          • 1970-01-01
          相关资源
          最近更新 更多