Построение Flame Chart для MSSQL

от автора

Если в вашем коде TSQL много вложенных вызовов stored procedures, вы можете наглядно построить стек вызовов с помощью «flame chart» — стандартным представлением для профилирования вызовов.

Опишем по шагам всю процедуру.

Создание трейса

Запустите SQL profiler и выберете события:

  • SP:Starting

  • SP:Completed

Выберите следующие колонки:

  • ObjectName

  • NestLevel

  • StartTime

  • EndTime

  • Spid

В фильтрах укажите условие по Spid на равенство — это важно. Анализируется только один поток выполнения. Записав достаточно событий, сохраните трейс в базу данных. В базе данных создайте следующую процедуру:

Скрытый текст
create procedure flame   @trname sysname, @spname sysname, @start int=0 as   -- Trace must contain Sp:Start, Sp:Completed, StartTime, EndTime, Nestlevel, ObjectName   -- 1 SPID should be recorded   set nocount on   declare @r int, @b int, @e int, @t datetime, @class int, @lev int, @obj varchar(255), @prevt datetime,      @stack varchar(max)='', @prevstack varchar(max)='', @sql varchar(1000)   create table #trace (RowNumber int, EventClass int, StartTime datetime, EndTime datetime, NestLevel int, ObjectName nvarchar(255))   set @sql = 'insert into #trace select RowNumber,EventClass,StartTime,EndTime,Nestlevel,ObjectName from '+@trname+' where EventClass in (42,43)'   exec (@sql)   select (select max(RowNumber) from #trace I where I.EventClass=42 and I.ObjectName=@spname and I.Nestlevel=1 and I.RowNumber<O.RowNumber) as [Start],     O.RowNumber as [End], StartTime, EndTime, datediff(ms, StartTime, endTime) as DurationMs     from #trace O where EventClass=43 and ObjectName=@spname and Nestlevel=1     order by 1   select @b=min(RowNumber) from #trace where EventClass=42 and ObjectName=@spname and NestLevel=1 and RowNumber>=@start   if @b is null begin print 'procedure: start not found' return end   select @e=min(RowNumber) from #trace where EventClass=43 and ObjectName=@spname and RowNumber>@b and Nestlevel=1   if @e is null begin print 'procedure: end not found' return end   select 'Selected', @b as [Start], @e as [End]   DECLARE my_cur CURSOR FOR SELECT RowNumber,EventClass,isnull(EndTime,StartTime),NestLevel,ObjectName      from #trace where RowNumber>=@b and RowNumber<=@e order by RowNumber   OPEN my_cur   FETCH NEXT FROM my_cur INTO @r, @class, @t, @lev, @obj   WHILE @@FETCH_STATUS = 0   BEGIN     if @class=42 set @stack = @stack + ';' + @obj else set @stack=reverse(substring(reverse(@stack),charindex(';', reverse(@stack))+1,100000)) if @prevt is not null print substring(@prevstack,2,100000)+' '+convert(varchar,datediff(ms,@prevt,@t)) set @prevt=@t set @prevstack=@stack     FETCH NEXT FROM my_cur INTO @r, @class, @t, @lev, @obj   END   CLOSE my_cur   DEALLOCATE my_cur GO

Генерация данных

Запустите процедуру flame указав параметры:

  • имя таблицы с трейсом

  • имя процедуры для построения диаграммы. Процедура должны быть на самом верхнем уровне вызова (NestLevel=1). Имя указывается без скобок и схемы, то есть вместо [dbo].[myProc] указываем myProc

  • третий параметр опционален, по умолчанию 0. Позволяет выбрать конкретное выполнение, если их много

Пример:

Первая табличка показывает все найденные выполнения данной функции, диапазон RowNumber, диапазон времен и длительность в миллисекундах

Если нас интересует не самое первое выполнение, то указываем в третьем параметре Start нужного нам. Во втором результате указывается выполнение, выбранное к анализу. Например, для 9го исполнения указываем значение 10574

Построение диаграммы

Убедившись, что все в порядке, заглянем во вкладку Messages и скопируем результат в текстовый файл, удалив в самом конце ненужное вместе с пустой строкой:

Далее идем на сайт https://www.speedscope.app и загружаем созданный нами файл. Готово.


ссылка на оригинал статьи https://habr.com/ru/articles/892876/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *