Замеряет скорость выполнения запроса и получает его выгрузки

SeiOkami 495 5 11 13

Иногда так нужно проанализировать время и результат сложного запроса прямо в отладке! Предлагаю свою версию решения этой задачки Несложная функция, которая клонирует переданный запрос и выполняет его пакеты с получением результата и замером времени. Учитывает все переданные параметры и временные таблицы в МВТ. И при этом не задевает переданный запрос! И он выполнится так же, словно вы ничего не совершали. Удобно, когда в запросе есть менеджер временных таблиц, который "сломает" повторное выполнение. Можно закинуть в общий модуль или просто во внешнюю обработку. В обоих случаях это удобно использовать прямо в отладке, когда все нужные данные запроса заполнены. Выкладываю функцию в FastCode. Она будет обновляться с учетом ваших пожеланий. С вас лишь скромный лайк на сайте. Он ничего не дает, но все равно приятно

Источник: https://t.me/JuniorOneS

// Замеряет скорость выполнения запроса и получает его выгрузки
// Возвращает результат анализа запроса и полученные данные. При этом переданный объект запроса не выполняется
// Удобно использовать в отладке для анализа запроса прямо с установленными параметрами и МВТ
// Функция будет поддерживаться и обновляться на FastCode: https://fastcode.im/Templates/7426
//
// 1. Выбирает все данные из менеджера временных таблиц
// 2. Создает копию запроса с новым менеджером таблиц
// 3. Выполняет копию запроса в разрезе пакетов
// 4. Замеряет скорость выполнения каждого пакета
// 5. Выбирает данные результатов выполнения
// 6. Возвращает результат анализа запроса
//
// Параметры:
//  ВходящийЗапрос  - Запрос - Анализируемый запрос
//
// Возвращаемое значение:
//   Таблица значений   - результат анализа
//
Функция ВыполнитьЗапросСАналитикой(ВходящийЗапрос) Экспорт
	
	ДанныеПакетов = Новый ТаблицаЗначений;
	
	ДанныеПакетов.Колонки.Добавить("НомерСтроки" , Новый ОписаниеТипов("Число"));
	ДанныеПакетов.Колонки.Добавить("Тип"         , Новый ОписаниеТипов("Строка"));
	ДанныеПакетов.Колонки.Добавить("ИмяТаблицы"  , Новый ОписаниеТипов("Строка"));
	ДанныеПакетов.Колонки.Добавить("Миллисекунды", Новый ОписаниеТипов("Число"));
	ДанныеПакетов.Колонки.Добавить("Записей"     , Новый ОписаниеТипов("Число"));
	ДанныеПакетов.Колонки.Добавить("ЕстьДанные"  , Новый ОписаниеТипов("Булево"));
	ДанныеПакетов.Колонки.Добавить("Данные"      , Новый ОписаниеТипов("ТаблицаЗначений"));
	
	ДанныеПакетов.Индексы.Добавить("ИмяТаблицы");
	
	Запрос = Новый Запрос;
	Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
	
	Если ВходящийЗапрос.МенеджерВременныхТаблиц <> Неопределено Тогда
		
		Для Каждого ВременнаяТаблица Из ВходящийЗапрос.МенеджерВременныхТаблиц.Таблицы Цикл
			
			ВыбираемыеПоля = Новый Массив;
			Для Каждого ОписаниеКолонки Из ВременнаяТаблица.Колонки Цикл
				ВыбираемыеПоля.Добавить(ОписаниеКолонки.Имя);
			КонецЦикла;
			
			Запрос.Текст = СтрШаблон("ВЫБРАТЬ %1 ПОМЕСТИТЬ %2 ИЗ &ВременнаяТаблица КАК ВТ", 
			СтрСоединить(ВыбираемыеПоля, ","), ВременнаяТаблица.ПолноеИмя);
			
			ДанныеВременнойТаблицы = ВременнаяТаблица.ПолучитьДанные().Выгрузить();
			Запрос.УстановитьПараметр("ВременнаяТаблица", ДанныеВременнойТаблицы);
			
			Запрос.Выполнить();
			
			ОписаниеПакета = ДанныеПакетов.Добавить();
			ОписаниеПакета.ИмяТаблицы  = ВременнаяТаблица.ПолноеИмя;
			ОписаниеПакета.Данные      = ДанныеВременнойТаблицы;
			ОписаниеПакета.ЕстьДанные  = Истина;
			ОписаниеПакета.Тип = "Таблица менеджера";
			
			Запрос.Текст = "";
			Запрос.Параметры.Удалить("ВременнаяТаблица");
			
		КонецЦикла;
		
	КонецЕсли;
	
	Для Каждого КлючИЗначение Из ВходящийЗапрос.Параметры Цикл
		Запрос.УстановитьПараметр(КлючИЗначение.Ключ, КлючИЗначение.Значение);
	КонецЦикла;
	
	СхемаЗапроса = Новый СхемаЗапроса;
	СхемаЗапроса.УстановитьТекстЗапроса(ВходящийЗапрос.Текст);
	Для Каждого ПакетЗапроса Из СхемаЗапроса.ПакетЗапросов Цикл
		
		ОписаниеПакета = ДанныеПакетов.Добавить();
		
		Если ТипЗнч(ПакетЗапроса) = Тип("ЗапросУничтоженияТаблицыСхемыЗапроса") Тогда
			
			Запрос.Текст = "УНИЧТОЖИТЬ " + ПакетЗапроса.ИмяТаблицы;
			ОписаниеПакета.ЕстьДанные  = Ложь;
			ОписаниеПакета.ИмяТаблицы = Запрос.Текст;
			ОписаниеПакета.Тип = "Уничтожение";
			
		Иначе
			
			ОписаниеПакета.ЕстьДанные  = Истина;
			Если ПустаяСтрока(ПакетЗапроса.ТаблицаДляПомещения) Тогда
				ОписаниеПакета.Тип = "Выборка";
			Иначе
				ОписаниеПакета.Тип = "Помещение";
				СуществующийПакет  = ДанныеПакетов.Найти(ПакетЗапроса.ТаблицаДляПомещения, "ИмяТаблицы");
				Если СуществующийПакет <> Неопределено Тогда
					Запрос.Текст = "УНИЧТОЖИТЬ " + ПакетЗапроса.ТаблицаДляПомещения;
					Запрос.Выполнить();
					ДанныеПакетов.Удалить(СуществующийПакет);
				КонецЕсли;
			КонецЕсли;
			
			ОписаниеПакета.ИмяТаблицы = ПакетЗапроса.ТаблицаДляПомещения;
			
			Запрос.Текст = ПакетЗапроса.ПолучитьТекстЗапроса();
			
		КонецЕсли;
		
		НачалоЗамера    = ТекущаяУниверсальнаяДатаВМиллисекундах();
		РезультатЗапрос = Запрос.Выполнить();
		КонецЗамера     = ТекущаяУниверсальнаяДатаВМиллисекундах();
		
		ОписаниеПакета.Данные       = ДанныеВременнойТаблицы;
		ОписаниеПакета.Миллисекунды = КонецЗамера-НачалоЗамера;
		
		Если ОписаниеПакета.ЕстьДанные Тогда
			Если ОписаниеПакета.Тип = "Выборка" Тогда
				ДанныеПакета = РезультатЗапрос.Выгрузить();
			Иначе
				ДанныеПакета = Запрос.МенеджерВременныхТаблиц.Таблицы.Найти(ОписаниеПакета.ИмяТаблицы).ПолучитьДанные().Выгрузить();
			КонецЕсли;
			ОписаниеПакета.Данные = ДанныеПакета;
		КонецЕсли;
		
	КонецЦикла;
	
	Для НомерСтроки = 1 По ДанныеПакетов.Количество() Цикл
		ОписаниеПакета = ДанныеПакетов[НомерСтроки-1];
		ОписаниеПакета.НомерСтроки = НомерСтроки;
		Если ОписаниеПакета.ЕстьДанные Тогда
			ОписаниеПакета.Записей = ОписаниеПакета.Данные.Количество();
			Если ОписаниеПакета.Записей = 0 Тогда
				ОписаниеПакета.ЕстьДанные = Ложь;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ДанныеПакетов;
	
КонецФункции
1

Комментарии

SeiOkami
#1, ред. 03 апреля 2021 20:34

Пример результата в отладке:
Пример результата в отладке.png


См. также

Определение длины строки в запросе методом половинного деления

Выгрузка запроса в XML. Выгрузка объекта

Выгрузка результата запроса в текстовый файл с разделителями

СтраницыСтатусаВыгрузкиДанных (БСП)

ЗафиксироватьВыполнениеВыгрузкиДанныхВРежимеДлительнойОперации (БСП)

Выгрузка Запроса в XML документ, в виде дерева(В Виде иерархии)

НастройкиТранспортаОбмена (БСП)

ЧисловыеПоказателиТекущихДел (БСП)

Модератору