欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

程序员文章站 2021-12-02 10:57:32
一.概念 SOS_SCHEDULER_YIELD等待类型是一个任务自愿放弃当前的资源占用,让给其他任务使用。 这个等待类型与CPU有直接关系,与内存与也有间接关系,与CPU有关系是因为在sql server里是通过任务调度SCHEDULER来关联CPU。 通过SCHEDULER下的Worker线程来 ......

 一.概念

   SOS_SCHEDULER_YIELD等待类型是一个任务自愿放弃当前的资源占用,让给其他任务使用。   这个等待类型与CPU有直接关系,与内存与也有间接关系,与CPU有关系是因为在sql server里是通过任务调度SCHEDULER来关联CPU。 通过SCHEDULER下的Worker线程来处理SQL任务。为什么跟内存有关系呢,是因为获取的资源需要内存来承载。 
  Yelding的发生:是指SCHEDULER上运行的Worker都是非抢占式的, 在 SCHEDULER上Worker由于资源等待,让出当前Worker给其它Worker就叫Yielding。 关于SCHEDULER_YIELD产生的原理查看  。SOS_SCHEDULER_YIELD 等待的情况可以了解到:

  (1)CPU有压力

  (2) SQL Server CPU scheduler 使用得当处理就会效率高。

1.1 从实例级别来查看等待数

select wait_type,
waiting_tasks_count,
wait_time_ms ,
max_wait_time_ms,
signal_wait_time_ms
from sys.dm_os_wait_stats
where wait_type like 'SOS_SCHEDULER_YIELD%' 
order by wait_type

  查询如下图所示: 

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

  这个等待类型排名第二,从请求的次数来说有69367060次,也就是说该线程用完了4ms的时间片,主动放弃cpu。如果没有大量的runnable队列或者大量的signal wait,证明不一定是cpu问题。因为这两个指标是cpu压力的一个体现。需要检查执行计划中是否存在大量扫描操作。

1.2 通过dmv scheaduler的描述查看cpu压力

SELECT scheduler_id, current_tasks_count, runnable_tasks_count, work_queue_count, pending_disk_io_count
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

  如下图所示:

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

  如果你注意到runnable_tasks_count计数有两位数,持续很长时间(一段时间内),你就会知道CPU压力。两位数字通常被认为是一件坏事 无法应对当前负荷。另外可以通过性能监视器%Processor Time 来查看CPU的状况。

1.3 通过案例实时查看sql语句级的资源等待

SELECT * FROM sys.dm_exec_requests  WHERE wait_type LIKE 'SOS_SCHEDULER_YIELD%'

  -- 或查找资源等待的
  SELECT session_id ,status ,blocking_session_id
  ,wait_type ,wait_time ,wait_resource
  ,transaction_id
  FROM sys.dm_exec_requests
  WHERE status = N'suspended';

  如下图所示 运行sys.dm_exec_requests 表,由于字段多截取了三断。会话202的sql 语句上一次 等待类型是SOS_SCHEDULER_YIELD。之所以会出现YIELD,是因为SCHEDULER下的Worker已经发起了task 命令,但由于资源等待 如锁或者磁盘输入/输出等,Worker又是非抢占式,所以让出了当前的Worker。

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

sql server 性能调优 资源等待之SOS_SCHEDULER_YIELD

1.4 减少sos_scheduler_yield 等待

  正如上面所讨论的,这种等待类型与CPU压力有关。增加更多CPU是简单的解决方案,然而实现这个解决方案并不容易。当这个等待类型很高时,你可以考虑其他的事情。这里通过从缓存中找到与CPU相关的最昂贵的SQL语句。

--查询编译以来 cpu耗时总量最多的前50条(Total_woker_time) 第一种查询
select
'total_worker_time(ms)'=(total_worker_time/1000),
q.[text], --DB_NAME(dbid),OBJECT_NAME(objectid),
execution_count,
'max_worker_time(ms)'=(max_worker_time/1000),
'last_worker_time(ms)'=(last_worker_time/1000),
'min_worker_time(ms)'=(min_worker_time/1000),
'max_elapsed_time(ms)'=(max_elapsed_time/1000),
'min_elapsed_time(ms)'=(min_elapsed_time/1000),
'last_elapsed_time(ms)'=(last_elapsed_time/1000),
total_physical_reads,
last_physical_reads,
min_physical_reads,
max_physical_reads,
total_logical_reads,
last_logical_reads,
max_logical_reads,
creation_time,
last_execution_time
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(highest_cpu_queries.plan_handle) as q
order by highest_cpu_queries.total_worker_time DESC