CPU性能瓶颈可以从计数器 Processor:%Processor .如果这个很高,还要再检查sql server的Process:%processor Time是否也很高,以确定是否是sql server消耗的
CPU.
CPU高的原因:
1.过度编译和重编译
2.排序和聚合计算
3.表格连接操作
4.低效的执行计划
5.并行查询
-
过度编译和重编译
编译是sql server为指令生成执行计划的过程。分析指令要做的事情,分析它要访问的表结构,以及上面的索引,还要分析表格里的数据分布,最后推断出一个认为比较优化的执行计划。这个过程主要是在做各种计算,所以说是使用CPU比较集中的地方。
重编译:很多时候,由于数据量发生了变化,或者表结构变化。同样的一句话,还要再次把执行计划再做一遍,这个过程就是重编译
看计数器 SQl Recompilations 对Batch Request /Sec 的比率和Sql Compilations 对 Batch Request /Sec 的比率。这个比率表示每秒请求的批处理中有多少个请求需要编译或者重编译。
一般建议重编译比率 不超过1%。 编译比率 不超过10%。
如果说这个比率比较高,需要跟踪一下。
–SP: Recompile –RPC: Completed –Auto Stats 引起重编译和编译的原因,可能有以下情况
1)set 语句的变化
2)统计信息发生变化
3)不明确的对象名称 --使用明确的对象名称
4)HINT提示 --去掉 WITH RECOMPILE
-
排序和聚合运算
在查询的时候,经常会做order by,distinct这样的操作,也会做avg,min,max,sum这样的聚合计算。在数据已经被加载到内存后,就要使用cpu把这些计算做完。所以这也是耗费cpu的地方。
-
表格join操作
当语句需要两张表做连接的时候,sql server常常会选择Nested Loop 或者hash算法。算法的完成要运行cpu。尤其是当sql server选择了错误的连接算法的时候。
-
低效的执行计划
1)过时的统计信息
2)缺失索引
3)错误的索引
4)代码质量
-
并行查询
如果查询的开销 > 并行的开销阈值 (默认为5 秒), 查询将会并行执行 在大多数情况下,并行能够加强查询的性能然而,一个给定查询的响应时间必须从整个系统的吞吐量和系统 上的其他查询出发来综合考虑。
比如说一条指令要读入100万条记录。如果一个线程做,可能需要10秒,如果10个线程做,每个线程读10万条记录,可能每个线程只需要1秒,就算加上线程间同步时间,可能总共2秒就完成了。缩短了查询的时间。但是在这2秒里,有10个cpu需要全力运行这10个线程,别的用户发过来的指令会受到影响,甚至可能会拿不到cpu执行。
对于并发度要求比较高,每个用户都要求有及时响应的OLTP系统,一般会建议设置每个指令都只用一个线程执行,从而保证SQL SERVER在任何一个时间点,都有多个CPU可以响应多个请求。即把 Max Degree of Parallelism 设成1.
对于并发用户比较少的,经常会有复杂查询的系统,可以把Max Degree of Parallelism的值设成cpu的数量值。如果也要考虑并发,可以设成小一点。
如果说当前系统cpu比较高,也可以通过动态管理视图来查询:
select
highest_cpu_queries.*,q.dbid,
q.objectid, q.number, q.encrypted, q.[text]
from
(select top 50 qs.*
from sys.dm_exec_query_stats qs
order by qs.total_worker_time desc) as highest_cpu_queries
cross apply sys.dm_exec_sql_text(plan_handle) as q
order by highest_cpu_queries.total_worker_time desc
go
或者找最经常做重编译的存储过程
select top 25 sql_text.text, sql_handle, plan_generation_num, execution_count,
dbid, objectid
from sys.dm_exec_query_stats a
cross apply sys.dm_exec_sql_text(sql_handle) as sql_text
where plan_generation_num >1
order by plan_generation_num desc
go