• sql server 的cpu使用率过高的分析


    有哪些SQL语句会导致CPU过高?

    1.编译和重编译

    编译是 Sql Server 为指令生成执行计划的过程。Sql Server 要分析指令要做的事情,分析它所要访问的表格结构,也就是生成执行计划的过程。这个过程主要是在做各种计算,所以CPU 使用比较集中的地方。

    执行计划生成后会被缓存在 内存中,以便重用。但是不是所有的都可以 被重用。在很多时候,由于数据量发生了变化,或者数据结构发生了变化,同样一句话执行,就要重编译。

    2.排序(sort) 和 聚合计算(aggregation)

    在查询的时候,经常会做 order by、distinct 这样的操作,也会做 avg、sum、max、min 这样的聚合计算,在数据已经被加载到内存后,就要使用CPU把这些计算做完。所以这些操作的语句CPU 使用量会多一些。

    3.表格连接(Join)操作

    当语句需要两张表做连接的时候,SQLServer 常常会选择 Nested Loop 或 Hash 算法。算法的完成要运行 CPU,所以 join 有时候也会带来 CPU 使用比较集中的地方。

    4.Count(*) 语句执行的过于频繁

    特别是对大表 Count() ,因为 Count() 后面如果没有条件,或者条件用不上索引,都会引起 全表扫描的,也会引起 CPU 的大量运算

    查看SQL语句CPU高的语句

    SELECT TOP 10 TEXT AS 'SQL Statement'
        ,last_execution_time AS 'Last Execution Time'
        ,(total_logical_reads + total_physical_reads + total_logical_writes) / execution_count AS [Average IO]
        ,(total_worker_time / execution_count) / 1000000.0 AS [Average CPU Time (sec)]
        ,(total_elapsed_time / execution_count) / 1000000.0 AS [Average Elapsed Time (sec)]
        ,execution_count AS "Execution Count",qs.total_physical_reads,qs.total_logical_writes
    --    ,qp.query_plan AS "Query Plan"
    FROM sys.dm_exec_query_stats qs
    CROSS APPLY sys.dm_exec_sql_text(qs.plan_handle) st
    --CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
    ORDER BY total_elapsed_time / execution_count DESC
    -- 若需要查看语句执行的计划,进一步分析语句,可以去掉注释,但可能导致查询结果变慢

    查询当前占用cpu时间比较多的语句

    SELECT TOP 10  dest.[text] AS 'sql语句' 
    ,der.[cpu_time] as 'cpu时间'
    FROM sys.[dm_exec_requests] AS der  CROSS APPLY  sys.[dm_exec_sql_text](der.[sql_handle]) AS dest  
     WHERE [session_id]>50  ORDER BY [cpu_time] DESC 

    优化手段

    • 通过服务端的推送,有事件告警或者解除过来才查询数据库。
    • 优化上述查询语句,比如count(*)可以用count(0)替代——参考《SQL开发技巧(二)
    • 优化语句,先查询出所有的MgrObjId,然后在做连接
    • 为管理对象、地点表等增加索引
    • 添加了索引之后,事件表的插入就会慢,能够再怎么优化呢?可以分区建立索引,每天不忙的时候,把新的记录移入到建好索引的分区

    总结

    • 服务器CPU过高,首先查看系统进程,确定引发CPU过高的进程
    • 通过SQLServer Profiler能够轻易监控到哪些SQL语句执行时间过长,消耗最多的CPU
    • 通过SQL语句是可以查看每条SQL语句消耗的CPU是多少
    • 导致CPU高的都是进行大量计算的语句:包括内存排序、表扫描、编译计划等。
    • 如果使用Top刷选前面几条语句,则尽量为Order By子句建立索引,这样可以减少对所有的刷选结果进行排序
    • 使用Count查询记录数时,尽量通过为where字句的相关字段建立索引以减少表扫描。如果多个表进行join操作,则把相关的表连接字段建立在包含索引中
    • 通过服务端通知的方式,减少SQL语句的查询
    • 通过表分区,尽量降低因为添加索引而导致表插入较慢的影响

     

    如果你是蜗牛,那你就不必害怕自己前进的缓慢,相信你自己,因为你的脚步永远不会落空,只要你一步步的向上爬,金字塔也必定被你踩在脚下。
  • 相关阅读:
    使用SpringAOP获取一次请求流经方法的调用次数和调用耗时
    疫苗之殇与理性应对之道
    【做更好的职场人】理性、弹性、开放的沟通
    使用IntelljIDEA生成接口的类继承图及装饰器模式
    订单导出应对大流量订单导出时的设计问题
    预发和线上的自动化对比工具微框架
    从实战角度看如何构建高质量的软件:一线工程师的一份质量手记
    代码问题及对策
    若干设计经验教训小记
    输入输出无依赖型函数的GroovySpock单测模板的自动生成工具(上)
  • 原文地址:https://www.cnblogs.com/lx823706/p/5069667.html
Copyright © 2020-2023  润新知