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

Откуда: Железнодорожный
Сообщений: 1842
Блог
Народ, решил запостить скрипт, который ищет пересекающиеся джобы. Возможно кому-то пригодиться для балансировки нагрузки на сервер во время выполнения задач. Так же поможет определить если два "тяжелых" (критичных джоба выполняются в одно и тоже время или пересекаются. Создавая излишнюю нагрузку на сервер, или блокировки.
use [msdb]
GO
with ste as(
select 
	jh.job_id,
	jh.step_id,
	convert(datetime,cast(jh.run_date as varchar(8)),112)+CONVERT(datetime,Tfull.T,108) as run_datetime,	
	convert(datetime,cast(jh.run_date as varchar(8)),112)+CONVERT(datetime,Tfull.T,108)+CONVERT(datetime,Tdfull.T,108) as end_datetime,
	CONVERT(datetime,Tdfull.T,108) as duration
from dbo.sysjobhistory as jh
cross apply(select T = right('00000'+cast(jh.run_time as varchar(6)),6))T
cross apply(select T = substring(T.T,1,2))Th
cross apply(select T = substring(T.T,3,2))Tm
cross apply(select T = substring(T.T,5,2))Ts
cross apply(select T = Th.T+':'+Tm.T+':'+Ts.T)Tfull
cross apply(select T = right('00000'+cast(jh.run_duration as varchar(6)),6))Td
cross apply(select T = substring(Td.T,1,2))Tdh
cross apply(select T = substring(Td.T,3,2))Tdm
cross apply(select T = substring(Td.T,5,2))Tds
cross apply(select T = Tdh.T+':'+Tdm.T+':'+Tds.T)Tdfull

where  jh.run_status = 1
and jh.step_id = 0 
)
SELECT ROW_NUMBER() over (partition by convert(varchar,a.run_datetime,112) order by a.run_datetime) as row_num,
	j.name,	
	a.step_id,
	a.run_datetime,
	a.end_datetime,
	a.duration,	
	j0.name,
	a0.step_id,
	a0.run_datetime,
	a0.end_datetime,
	a0.duration
  FROM ste as a
  JOIN ste as a0    ON a.job_id <> a0.job_id
  join dbo.sysjobs as j on j.job_id = a.job_id
  join dbo.sysjobs as j0 on j0.job_id = a0.job_id
   AND a0.end_datetime >= a.run_datetime
   AND a.end_datetime >= a0.run_datetime
/* Не учитывать перечисленные джобы при сравнении.
   where a.job_id not in ('2FB67516-3465-49FC-B133-09B722459ECB')
   and a0.job_id not in ('2FB67516-3465-49FC-B133-09B722459ECB')
*/
GO

При
jh.step_id = 0 
учитывается итоговое выполнение джоба. Например джоб А пересекался с джобом Б.
При
jh.step_id != 0 -- или jh.step_id > 0
учитывается выполнение каждого шага джоба. Например джоб А на 2-ом шаге пересекался с джобом Б на 4-ом шаге.

У кого буду мысли/критика по оптимизации скрита с удовольствием выслушаю.
Сдам в ремонт свою крышу, чтоб больше не ехала, как у Чехова.
22 ноя 11, 15:32    [11638348]     Ответить | Цитировать Сообщить модератору
 Re: Поиск пересекающихся джобов.  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
gds
Народ, решил запостить скрипт, который ищет пересекающиеся джобы. Возможно кому-то пригодиться для балансировки нагрузки на сервер во время выполнения задач. Так же поможет определить если два "тяжелых" (критичных джоба выполняются в одно и тоже время или пересекаются. Создавая излишнюю нагрузку на сервер, или блокировки.


Просто отличный скрипт, спасибо!

Из мелких замечаний duration лучше сразу к time приводить, если версия сервера позволяет(можно и на ходу проверять)
ну и для исключения хорошо бы выводить a.jobid and a0.jobid где-то в стороне
22 ноя 11, 20:14    [11640524]     Ответить | Цитировать Сообщить модератору
 Re: Поиск пересекающихся джобов.  [new]
gds
Member

Откуда: Железнодорожный
Сообщений: 1842
Блог
Andrey Sribnyak
Из мелких замечаний duration лучше сразу к time приводить,

К сожалению у меня как 2005 так и 2008R2. т.ч. пока рано об этом говорить. Но выглядит конечно красивее.
Хотя можно и функцию использовать или добавить в запрос через cross apply.
create function dbo.uf_getTime (
	@date_start datetime,
	@date_end datetime
)
 returns varchar(16)
as 

begin
declare @res varchar(16)

select @res =	replace(str(datediff(dd, '19000101', diff),7),' ','')	+':'+
				replace(str(datepart(hh, diff),2),' ','0') +':'+ 
				replace(str(datepart(mi, diff),2),' ','0') +':'+
				replace(str(datepart(ss, diff),2),' ','0') 	
from (select @date_end - @date_start [diff]) t
return @res
end

Andrey Sribnyak
ну и для исключения хорошо бы выводить a.jobid and a0.jobid где-то в стороне

Да, если они Вам нужны можете выводить в стороне. Например для добавления в исключения.
23 ноя 11, 09:23    [11642043]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить