Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Узнать нагрузку CPU через запрос на текущий момент времени  [new]
andrew shalaev
Member

Откуда: Moscow
Сообщений: 610
Доброго времени суток!

СУБД: SQL Server 2005

Вопрос собственно в теме, необходимо через запрос получить значение нагрузки CPU на сервере на момент запуска запроса. Подскажите через какое представление получить инфу?
29 май 13, 17:20    [14366066]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Glory
Member

Откуда:
Сообщений: 104751
andrew shalaev
необходимо через запрос получить значение нагрузки CPU на сервере на момент запуска запроса.

А как вы определяете "момент запуска запроса" ?
29 май 13, 17:22    [14366082]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
komrad
Member

Откуда:
Сообщений: 5674
andrew shalaev,


+
	
	declare @cpu_sql tinyint
	declare @cpu_system tinyint
	declare @cpu_other tinyint
	declare @cpu_sql_avg tinyint
	declare @cpu_system_idle_avg tinyint
	declare @cpu_other_avg tinyint

	select top 1 @cpu_sql	=	SQLProcessUtilization,
				@cpu_system	=	SystemIdle,
				@cpu_other	=	100 - SystemIdle - SQLProcessUtilization 
	from (
		select 
			record.value('(./Record/@id)[1]', 'int') as record_id,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
			timestamp
		from (
			select timestamp, convert(xml, record) as record 
			from master.sys.dm_os_ring_buffers 
			where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
			and record like '%<SystemHealth>%') as x
		) as y 
	order by record_id desc

	select	@cpu_sql_avg			=	avg(SQLProcessUtilization) ,
			@cpu_system_idle_avg	=	avg(SystemIdle) ,
			@cpu_other_avg			=	avg(Others)
	from (
	select top 30 SQLProcessUtilization,
					SystemIdle,
					100 - SystemIdle - SQLProcessUtilization  as Others
	from (
		select 
			record.value('(./Record/@id)[1]', 'int') as record_id,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
			timestamp
		from (
			select timestamp, convert(xml, record) as record 
			from master.sys.dm_os_ring_buffers 
			where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
			and record like '%<SystemHealth>%') as x
		) as y 
	order by record_id desc) as t


	select	'Current CPU SQL/Others/Idle, %', 
			convert(varchar(3),@cpu_sql) +'/'+convert(varchar(3),@cpu_other) +'/'+convert(varchar(3),@cpu_system)
	union
	select	'AVG CPU SQL/Others/Idle (Last 30), %', 
			convert(varchar(3),@cpu_sql) +'/'+convert(varchar(3),@cpu_other) +'/'+convert(varchar(3),@cpu_system)						
29 май 13, 17:41    [14366192]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
komrad
Member

Откуда:
Сообщений: 5674
сорри,
исправил опечатки в скрипте

+
	declare @cpu_sql tinyint
	declare @cpu_system tinyint
	declare @cpu_other tinyint
	declare @cpu_sql_avg tinyint
	declare @cpu_system_idle_avg tinyint
	declare @cpu_other_avg tinyint

	select top 1 @cpu_sql	=	SQLProcessUtilization,
				@cpu_system	=	SystemIdle,
				@cpu_other	=	100 - SystemIdle - SQLProcessUtilization 
	from (
		select 
			record.value('(./Record/@id)[1]', 'int') as record_id,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
			timestamp
		from (
			select timestamp, convert(xml, record) as record 
			from master.sys.dm_os_ring_buffers 
			where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
			and record like '%<SystemHealth>%') as x
		) as y 
	order by record_id desc

	select	@cpu_sql_avg			=	avg(SQLProcessUtilization) ,
			@cpu_system_idle_avg	=	avg(SystemIdle) ,
			@cpu_other_avg			=	avg(Others)
	from (
	select top 30 SQLProcessUtilization,
					SystemIdle,
					100 - SystemIdle - SQLProcessUtilization  as Others
	from (
		select 
			record.value('(./Record/@id)[1]', 'int') as record_id,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
			record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
			timestamp
		from (
			select timestamp, convert(xml, record) as record 
			from master.sys.dm_os_ring_buffers 
			where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
			and record like '%<SystemHealth>%') as x
		) as y 
	order by record_id desc) as t


	select	'Current CPU SQL/Others/Idle, %', 
			convert(varchar(3),@cpu_sql) +'/'+convert(varchar(3),@cpu_other) +'/'+convert(varchar(3),@cpu_system)
	union
	select	'AVG CPU SQL/Others/Idle (Last 30), %', 
			convert(varchar(3),@cpu_sql_avg) +'/'+convert(varchar(3),@cpu_other_avg) +'/'+convert(varchar(3),@cpu_system_idle_avg)			
			
29 май 13, 17:46    [14366208]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
andrew shalaev
Member

Откуда: Moscow
Сообщений: 610
komrad,

Спасибо за срипт, однако он собирает данные за 1 минуту, т.е. в течении 1 минуты показатели будут одинаковые. хотя на деле нагрузка изменяется каждую секунду. Я имел ввиду есть ли скрипт который показывает нагрузку за интервал времени 1 секунду или меньше.
29 май 13, 18:37    [14366373]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
komrad
Member

Откуда:
Сообщений: 5674
andrew shalaev,

тогда Performance counters в помощь
29 май 13, 18:54    [14366416]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37228
andrew shalaev
komrad,

Спасибо за срипт, однако он собирает данные за 1 минуту, т.е. в течении 1 минуты показатели будут одинаковые. хотя на деле нагрузка изменяется каждую секунду. Я имел ввиду есть ли скрипт который показывает нагрузку за интервал времени 1 секунду или меньше.
Нагрузка меняется каждый такт, если что. Кстати, сам по себе показатель нагрузки на процессор - абсолютно бесполезная вещь.
29 май 13, 19:05    [14366469]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Crimean
Member

Откуда:
Сообщений: 13147
а для чего нужна такая информация сама по себе?
я понимаю 2 варианта (в рамках этой конфы):
1.узнать какой % нагрузки дает сам сиквел как сервис - тут надо возвращать пару цифр - общий % и % от нужного сервиса. и за минуту - более чем показательно. узнавать через АПИ у операционки
2.узнать какой % нагрузки дает какой процесс сиквела. тут можно собирать дельты cpu по dmv для процессов и выводить кто жрал проц ту же последнюю минуту
29 май 13, 19:11    [14366484]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Crimean
2.узнать какой % нагрузки дает какой процесс сиквела. тут можно собирать дельты cpu по dmv для процессов и выводить кто жрал проц ту же последнюю минуту
проблема только в том, что в dmv по процессам значения cpu некорректные.
Лучше сразу смотреть в сторону sp_WhoIsActive, там поигравшись с параметрами можно получить правильную дельту.
29 май 13, 19:28    [14366537]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Crimean
Member

Откуда:
Сообщений: 13147
Mind
проблема только в том, что в dmv по процессам значения cpu некорректные


облин, да? а мне казалось что по дельте cpu можно неплохо выявлять кто пожрал проц за последний минут
30 май 13, 10:53    [14368582]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
andrew shalaev
Member

Откуда: Moscow
Сообщений: 610
Crimean
а для чего нужна такая информация сама по себе?


Данная информация нужна для сбора краткой информации по активности сервера. Мысль следующая, каждый краткий промежуток времени(пока думаю раз в минуту) запускается скрипт:
+

DECLARE @count_proc int
DECLARE @RCPT2 VARCHAR(400)
DECLARE @MSG VARCHAR(400)
declare @waittype varchar(100)
declare @waittype_count int 
declare @lock_cont int
declare @cpu int  
DECLARE @ts_now bigint 


--CPU%
SELECT @ts_now = cpu_ticks / CONVERT(float, cpu_ticks_in_ms) FROM sys.dm_os_sys_info 

    SELECT TOP(1) @cpu =  SQLProcessUtilization +  (100 - SystemIdle - SQLProcessUtilization)
    FROM ( 
          SELECT record.value('(./Record/@id)[1]', 'int') AS record_id, 
                record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') 
                AS [SystemIdle], 
                record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 
                'int') 
                AS [SQLProcessUtilization], [timestamp] 
          FROM ( 
                SELECT [timestamp], CONVERT(xml, record) AS [record] 
                FROM sys.dm_os_ring_buffers 
                WHERE ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR' 
                AND record LIKE '%<SystemHealth>%') AS x 
          ) AS y 
    ORDER BY record_id DESC;

--lock count
select @lock_cont = count(*)
from sys.sysprocesses 
where spid > 50 and spid <> @@spid and status <> 'sleeping' and blocked <> 0

--most waittype
select  lastwaittype,  count(*) as [count]
into #t1
From sys.sysprocesses where spid > 50 and spid <> @@spid and status <> 'sleeping'
group by lastwaittype

select @waittype = lastwaittype, @waittype_count =  [count]
from #t1  
where [count] = (select MAX([count]) from #t1)

--active proc count
select @count_proc = count(*)
from sys.sysprocesses 
where spid > 50 and spid <> @@spid and status <> 'sleeping'
if @count_proc > 60 
begin
--send sms
SET @MSG ='user_proc='+ convert(varchar(10), @count_proc)+','+ltrim(rtrim(@waittype))+'='+convert(varchar(10), @waittype_count)+', lock='+
convert(varchar(10), ltrim(rtrim(@lock_cont)))+' CPU%='+convert(varchar(10), ltrim(rtrim(@cpu)))
DECLARE @MSG2 VARCHAR(400)
SET @MSG2 =''

EXEC msdb.dbo.sp_send_dbmail
@profile_name = admin, 
@recipients = '', 
@body = @MSG2  
end
else 
begin
SET @MSG ='user_proc='+ convert(varchar(10), @count_proc)+','+ltrim(rtrim(@waittype))+'='+convert(varchar(10), @waittype_count)+', lock='+
convert(varchar(10), ltrim(rtrim(@lock_cont)))+' CPU%='+convert(varchar(10), ltrim(rtrim(@cpu)))
select @MSG
drop table #t1
end



Который в случае срабатывания условий(большая очередь процессов) отсылает смс с краткой информацией.
Кстати, может у кого какие идеи какие еще параметры можно добавить в строку?
30 май 13, 10:57    [14368617]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Glory
Member

Откуда:
Сообщений: 104751
andrew shalaev
Который в случае срабатывания условий(большая очередь процессов)

А что среди стандартных Alert-ов не нашлось аналогов вашему "большая очередь процессов" ?
30 май 13, 11:00    [14368639]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
andrew shalaev
Member

Откуда: Moscow
Сообщений: 610
Glory,

Ну вот приятен процесс написание таких вот вещей )
30 май 13, 11:01    [14368643]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Glory
Member

Откуда:
Сообщений: 104751
andrew shalaev
Ну вот приятен процесс написание таких вот вещей )

Ну так вы можете создавать алерты и программным кодом

USE [msdb]
GO
EXEC msdb.dbo.sp_add_alert @name=N'MyAlert', 
		@enabled=1, 
		@delay_between_responses=0, 
		@include_event_description_in=0, 
		@performance_condition=N'MSSQL$KILIMADJARO:Resource Pool Stats|CPU usage %|default|>|50', 
		@job_id=N'00000000-0000-0000-0000-000000000000'
GO
EXEC msdb.dbo.sp_add_notification @alert_name=N'MyAlert', @operator_name=N'MyOperator', @notification_method = 7
GO
30 май 13, 11:08    [14368697]     Ответить | Цитировать Сообщить модератору
 Re: Узнать нагрузку CPU через запрос на текущий момент времени  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Crimean
Mind
проблема только в том, что в dmv по процессам значения cpu некорректные


облин, да? а мне казалось что по дельте cpu можно неплохо выявлять кто пожрал проц за последний минут
Если мне не изменяет память, при распаралеленном запросе, оно покажет CPU только одного потока, а именно управляющего, что, как можно догадаться, не имеет ничего общего с реальным потреблением.

http://sqlblog.com/blogs/adam_machanic/archive/2011/04/28/who-is-active-s-hidden-gems-a-month-of-activity-monitoring-part-2f-30.aspx
Search for "Accurate CPU Time Deltas"
30 май 13, 11:09    [14368704]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить