Раскраска листинга процедуры T-SQL значениями метрик
Сразу покажу, о чем идет речь, чтобы вы решили, нужно вам это или нет.

К операторам Tsql процедуры мы дописываем количество выполнений (x), cpu в миллисекундах ©, duration в микросекундах (d), число чтений ®, записей (w), число записей @@rowcount (n)
Можно показать как абсолютные значения, так и проценты
Сбор данных
Запустите SQL profielr и выберите единственное событие:
SP: StmtCompleted
Выберите следующие колонки:
CPU
Duration
Reads
Writes
StartTime
EndTime
LineNumber
ObjectName
SPID
RowCounts
Иногда данные в RowCounts не собираются, если не указано TextData.
В фильтрах укажите ObjectName = имя процедуры. Имя процедуры указывается без схемы и скобок, например, для процедуры [dbo].[MyProc] укажите просто MyProc
Если вы профилируете процедуру на dev и знаете SPID, то укажите его. Для Production старайтесь ограничить объем информации единственным SPID, хотя для самой программы разметки это необязательно.
Меня спрашивали, почему я использую SQL profiler, а не Extended Events. Вы можете использовать и их. Для коротких ad hoc трейсов иногда проще и быстрее сделать трейс с помощью SQL profiler. На production, конечно, надо быть осторожным, чтобы не получить runaway trace.
После запуска трейса соберите достаточно данных и запишите их в таблицу.
Подготовка окружения
Вам понадобится Python. Скачайте пакет pygments Welcome! — Pygments:
pip install Pygments
У вас появилась команда pygmentize. Скачайте еще один скрипт из моего репозитория:
https://github.com/tzimie/sqlpig
Проект первоначально назывался SQLpyg (SQL + pygmentize), но потом превратился в SQLpig.
В самом начале скрипта sqlpig.py есть запрос, который вам понадобится:
select ObjectName+'.sql:'+convert(varchar,LineNumber)+':'+
convert(varchar,cnt)+':'+
convert(varchar,CPU)+':'+
convert(varchar,Duration)+':'+
convert(varchar,Reads)+':'+
convert(varchar,Writes)+':'+
convert(varchar,isnull(RowCounts,0))
from (
select ObjectName,LineNumber, count(*) as cnt, sum(CPU) as CPU,sum(Duration) as Duration,
sum(Reads) as Reads, sum(Writes) as Writes, sum(RowCounts) as RowCounts
from {MyTrace} where EventClass=45 and ObjectName is not null
group by ObjectName,LineNumber) Q
Только замените {MyTrace} на имя таблицы, куда вы записали трейс. Выполните скрипт и его вывод запишите в текстовый файл (.log). Можно назвать этот файл также, как и процедуру, либо добавлять суффикс short, long для разных выполнений.
Наконец, нам понадобится исходный текст процедуры. В Management Studio сделайте Alter для процедуры и скопируйте полученный текст в файл имяпроцедуры.sql
Внимание: вам надо удалить заголовок:

Первой должна стать первая значимая строка — ALTER или первая строка комментария.
Вы можете спросить -, а почему, собственно, скрипт не может сам прочитать данные и текст процедуры и трейс? Дело в том, что трейс делается на production, а на сервере часто ставить ничего нельзя. Поэтому тащим все на свой комп через copy/paste (если он включен)
Обработка
Запустим sqlpig:

Метрики из myproc.log накладываются на файл myproc.sql и выводятся в myproc.html. Можно указать разные метрики:
x — число выполнений, не самой процедуры, а оператора, если он в цикле, то число выполнений может быть куда больше, чем число выполнений процедуры
c — CPU в ms
d — duration в микросекундах (более точно, чем CPU)
r — Reads
w — Writes
n — число записей из колонки RowCounts (оно не всегда честное и заслуживает отдельного разговора)
XCDRWN — uppercase метрики — это те же метрики, но в процентах к полной сумме
Возможно указать как процентные, так и абсолютные метрики, например, xcCdD валидная комбинация.
Последний параметр — это имя log файла. К одной процедуре у вас могут быть собраны результаты многих прогонов, например,

Возможные проблемы
Иногда точки с метриками оказываются смещенными относительно строк исходного кода. Я постепенно вычищу краевые случаи, пока можно исправить значение в исходном коде:
shift = 1 # edit this value to readjust position if needed