【问题标题】:SQL Server 2012 CPU usage spikes to 100%SQL Server 2012 CPU 使用率飙升至 100%
【发布时间】:2015-07-20 03:44:02
【问题描述】:

我使用的是SQL Server 2014 in AWS,AWS 镜像配置是 4 核和 16GB RAM(m3.xlarge)。我正在运行以下简单查询,

SELECT * FROM user_table WHERE user_id = '10'

user_table 包含 1000k 条记录,user_id 是主键。当通过 EJB 休眠从我的应用程序执行上述简单查询时,CPU 会在一段时间内飙升至 10%,然后又恢复正常。

所以我的用例是,100 个用户将同时尝试访问应用程序,因此在几分之一秒内,上述查询将在几分之一秒内尝试执行 100 次。因此 CPU 使用率飙升至 100%。一旦所有查询执行完成,CPU 使用率就会恢复到 1% 的正常水平。

  • 为什么会这样?我是否需要增加我的 AWS 实例类型?
  • 我应该怎么做才能使 SQL Server 处理 100 或更多的并发命中而不造成高 CPU 使用率?如果我的查询如此复杂,那么可能有机会获得峰值,但我的查询很简单直接。
  • 是否有任何可用于 SQL Server 2014 的基准指标?
  • 任何解决方案通过低 CPU 使用率来支持 SQL Server 的并发命中?

编辑 1:

  • 我的数据文件大小约为32.2GB 和日志 我的数据库的文件大小约为894mb

  • 我的数据库具有READ_COMMITTED_SNAPSHOT is set to ON 的隔离级别。 但是当我尝试通过设置READ_COMMITTED_SNAPSHOT to OFF 时,性能提升有 20% 的差异,但性能提升并没有那么大。

【问题讨论】:

  • 我读过一些关于 sql server 中 CPU 峰值的文章,故障是 windows server 上的电源配置设置,但我不认为 AWS 在 windows server 上运行?
  • user_id 列的类型是什么?
  • user_id 是 BIGINT 类型。
  • 这个应该被移到 DBA 堆栈溢出站点以获得更好的答案
  • 能否请您在问题中添加您的查询计划。

标签: sql-server hibernate amazon-web-services sql-server-2012


【解决方案1】:

我会在键上创建一个聚集索引,因为在您定义一个之前,所有内容都存储在堆上。这可能导致搜索时 CPU 使用率过高(即使它在内存中)

Link to MSDN Article

具体来说

如果表是堆并且没有任何非聚集索引,则必须检查整个表(表扫描)以找到任何行。这在表格很小的情况下是可以接受的,例如公司 12 个区域办事处的列表。

警告:

警告创建或删除聚集索引需要重写 整张桌子。如果表有非聚集索引,所有 非聚集索引必须全部重新创建,无论何时聚集 索引变了。因此,从堆更改为聚集索引 结构或背部可能需要大量时间并且需要磁盘空间 重新排序 tempdb 中的数据。

这个 SQL 应该可以解决问题(一旦你在某处得到了很好的备份)

CREATE CLUSTERED INDEX IDX_UserID on user_table(User_ID)

普通索引也应该可以正常工作,但您应该始终使用聚集索引来对数据进行合理排序,然后使用任何其他高使用率索引。

【讨论】:

  • 他确实说过 user_id 是主键,默认情况下是聚集索引。
【解决方案2】:

用这么少的数据很难确定(读起来不可能),但对我来说这听起来很完美:100%CPU 意味着 sql-server 完全不受 IO 限制,但只使用 CPU 来执行查询,所以它可能会在内存中找到所需的一切,并且它还能够利用所有 CPU,因此也没有瓶颈。

所以只要性能足够,就不用担心。当然,一旦更多的查询进入系统,事情可能会变得更有趣。我期望的一件事是数据库缓存中的内容会消失,因此 CPU 负载会下降,而 IO 会增加并且性能会下降。

【讨论】:

  • 感谢您的回复,我已经编辑了我的问题多一点。我的编辑有什么直觉吗??
【解决方案3】:

您可以采取以下方法:

  1. 如果您的大多数查询都基于 user_id 列作为 where 子句,则在 user_id 列上为表建立索引。
  2. 正如您所说,每次运行查询时 CPU 都会出现峰值,这意味着 CPU 周期会花费在为查询生成计划上,这不应该是这种情况,因为下次运行查询时应该重用计划。检查PARAMETRIZATION
  3. 请考虑 PARTITIONING 是否是应用于表的选项。
  4. 假设如果 100 个用户连接到实例同时执行相同的查询会发生什么,我建议您运行 SQLQueryStress 工具并在帮助下观察实例的行为sp_AskBrent。这些结果将帮助您确定根本问题或根本原因。

【讨论】:

    【解决方案4】:

    您是否运行 SQL Profiler 以确保没有其他查询导致 CPU 峰值?

    【讨论】:

      【解决方案5】:

      您是否为您的数据库编制了索引?如果没有,请对其进行索引。索引对数据访问时间产生巨大影响。我认为滞后不是休眠的问题。您只需索引数据库并尝试查询。

      【讨论】:

        【解决方案6】:

        如果 user_id 是 BIGINT,则查询不是

        SELECT * FROM user_table WHERE user_id = 10
        

        数据转换的成本可能很高,具体取决于查询运行的次数

        【讨论】:

        • 我同意你的观点,因为我不喜欢使用错误的类型/语法,但它在这里应该没有效果,因为 sql server 只会对整个查询进行 1 次转换(常量 '10 ' 转换为 bigint)
        【解决方案7】:

        如果您查看了您的执行计划(在 SQL Server Management Studio 中激活“包括实际执行计划”按钮),运行查询时唯一需要查看的内容应该是:

        select 0%

        如果不是:此表上的索引有问题。如果 user_id 是唯一的,则其上应该有唯一的聚集索引。

        试一试;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-10-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-13
          • 2017-03-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多