mg娱乐电子4355_mg娱乐电子游戏平台
做最好的网站

转--也不知是哪位大侠写的了

时间:2019-11-10 03:17来源:计算机数据
 一.概念   SOS_SCHEDULER_YIELD等待类型是一个任务自愿放弃当前的资源占用,让给其他任务使用。  这个等待类型与CPU有直接关系,与内存与也有间接关系,与CPU有关系是因为在sqlserve

 一.概念

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

mg娱乐电子4355,  查询如下图所示: 

mg娱乐电子4355 1

  这个等待类型排名第二,从请求的次数来说有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

  如下图所示:

mg娱乐电子4355 2

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

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

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

  -- 或查找资源等待的
mg娱乐电子游戏平台,  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。

mg娱乐电子4355 3

mg娱乐电子4355 4

mg娱乐电子4355 5

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

 

试应用环境:SQL2008 R2、SQL2012、SQL2014

[sql] view plaincopy
--语句1:获取前20逻辑读取次数或逻辑写入次数或CPU 时间  
SELECT TOP 20 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,  
((CASE qs.statement_end_offset  
WHEN -1 THEN DATALENGTH(qt.TEXT)  
ELSE qs.statement_end_offset  
END - qs.statement_start_offset)/2)+1),  
qs.execution_count,  
qs.total_logical_reads, qs.last_logical_reads,  
qs.total_logical_writes, qs.last_logical_writes,  
qs.total_worker_time,  
qs.last_worker_time,  
qs.total_elapsed_time/1000000 total_elapsed_time_in_S,  
qs.last_elapsed_time/1000000 last_elapsed_time_in_S,  
qs.last_execution_time,  
qp.query_plan  
FROM sys.dm_exec_query_stats qs  
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt  
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp  
ORDER BY qs.total_logical_reads DESC -- 逻辑读取次数  
 --ORDER BY qs.total_logical_writes DESC -- 逻辑写入次数  
 --ORDER BY qs.total_worker_time DESC -- CPU 时间  


--语句2:获取前20执行的 SP 命令的总工作时间 (CPU 压力)  
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_worker_time AS 'TotalWorkerTime',   
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',  
    qs.execution_count AS 'Execution Count',   
    ISNULL(qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()), 0) AS 'Calls/Second',  
    ISNULL(qs.total_elapsed_time/qs.execution_count, 0) AS 'AvgElapsedTime',   
    qs.max_logical_reads, qs.max_logical_writes,   
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'  
    FROM sys.dm_exec_query_stats AS qs  
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt  
    WHERE qt.dbid = db_id() -- 当前数据库  
    ORDER BY qs.total_worker_time DESC  

--语句3: 获取前20 执行的 SP 命令逻辑写入/分钟  
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_logical_writes, qs.total_logical_writes/qs.execution_count AS 'AvgLogicalWrites',  
    qs.total_logical_writes/DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Logical Writes/Min',    
    qs.execution_count AS 'Execution Count',   
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',   
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',  
    qs.total_worker_time AS 'TotalWorkerTime',  
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',  
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads,   
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache',  
    qs.total_physical_reads/qs.execution_count AS 'Avg Physical Reads', qt.dbid  
    FROM sys.dm_exec_query_stats AS qs  
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt  
    WHERE qt.dbid = db_id() -- 当前数据库  
    ORDER BY qs.total_logical_writes DESC  

--语句4: 获取前20执行的 SP 命令的逻辑读取(内存压力)   
    SELECT TOP 20 qt.text AS 'SP Name', total_logical_reads,   
    qs.execution_count AS 'Execution Count', total_logical_reads/qs.execution_count AS 'AvgLogicalReads',  
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',   
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',  
    qs.total_worker_time AS 'TotalWorkerTime',  
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',  
    qs.total_logical_writes,  
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads,   
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache', qt.dbid   
    FROM sys.dm_exec_query_stats AS qs  
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt  
    WHERE qt.dbid = db_id() -- 当前数据库  
    ORDER BY total_logical_reads DESC  

--语句5: 获取前20执行的 SP 命令由物理读取 (读取 I/O 压力)  
    SELECT TOP 20 qt.text AS 'SP Name', qs.total_physical_reads, qs.total_physical_reads/qs.execution_count AS 'Avg Physical Reads',  
    qs.execution_count AS 'Execution Count',  
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',    
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',  
    qs.total_worker_time AS 'TotalWorkerTime',  
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',  
    qs.max_logical_reads, qs.max_logical_writes,    
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache', qt.dbid   
    FROM sys.dm_exec_query_stats AS qs  
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt  
    WHERE qt.dbid = db_id() -- 当前数据库  
    ORDER BY qs.total_physical_reads DESC  

--语句6: 获取前20执行的 SP 命令执行计数  
    SELECT TOP 20 qt.text AS 'SP Name', qs.execution_count AS 'Execution Count',    
    qs.execution_count/DATEDIFF(Second, qs.creation_time, GetDate()) AS 'Calls/Second',  
    qs.total_worker_time/qs.execution_count AS 'AvgWorkerTime',  
    qs.total_worker_time AS 'TotalWorkerTime',  
    qs.total_elapsed_time/qs.execution_count AS 'AvgElapsedTime',  
    qs.max_logical_reads, qs.max_logical_writes, qs.total_physical_reads,   
    DATEDIFF(Minute, qs.creation_time, GetDate()) AS 'Age in Cache'  
    FROM sys.dm_exec_query_stats AS qs  
    CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt  
    WHERE qt.dbid = db_id() -- Filter by current database  
    ORDER BY qs.execution_count DESC  

查看10秒时间内存储过程执行次数和CPU时间
[sql] view plaincopy在CODE上查看代码片派生到我的代码片
SELECT DB_NAME(st.dbid) DBName  
      ,OBJECT_SCHEMA_NAME(st.objectid,dbid) SchemaName  
      ,OBJECT_NAME(st.objectid,dbid) StoredProcedure  
      ,max(cp.usecounts) Execution_count  
      ,sum(qs.total_worker_time) total_cpu_time  
      ,sum(qs.total_worker_time) / (max(cp.usecounts) * 1.0)  avg_cpu_time  
 into #temp  
 FROM sys.dm_exec_cached_plans cp join sys.dm_exec_query_stats qs on cp.plan_handle = qs.plan_handle  
      CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st  
 where DB_NAME(st.dbid) is not null and cp.objtype = 'proc'  
 group by DB_NAME(st.dbid),OBJECT_SCHEMA_NAME(objectid,st.dbid), OBJECT_NAME(objectid,st.dbid)   
 order by sum(qs.total_worker_time) desc  

WAITFOR DELAY '00:00:10'   

SELECT DB_NAME(st.dbid) DBName  
      ,OBJECT_SCHEMA_NAME(st.objectid,dbid) SchemaName  
      ,OBJECT_NAME(st.objectid,dbid) StoredProcedure  
      ,max(cp.usecounts) Execution_count  
      ,sum(qs.total_worker_time) total_cpu_time  
      ,sum(qs.total_worker_time) / (max(cp.usecounts) * 1.0)  avg_cpu_time  
 into #temp2  
 FROM sys.dm_exec_cached_plans cp join sys.dm_exec_query_stats qs on cp.plan_handle = qs.plan_handle  
      CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st  
 where DB_NAME(st.dbid) is not null and cp.objtype = 'proc'  
 group by DB_NAME(st.dbid),OBJECT_SCHEMA_NAME(objectid,st.dbid), OBJECT_NAME(objectid,st.dbid)   
 order by sum(qs.total_worker_time) desc  

SELECT a.DBNAMe, a.SchemaName, a.StoredProcedure,  
b.Execution_count - a.Execution_count as ExecCnt,  
b.total_cpu_time - a.total_cpu_time as CPU   
FROM #temp a inner join #temp2 b on a.DBName = b.DBname and a.SchemaName = b.SchemaName and a.StoredProcedure = b.StoredProcedure  
ORDER BY 5 desc  

drop table #temp  
drop table #temp2   

  

编辑:计算机数据 本文来源:转--也不知是哪位大侠写的了

关键词: