Статьи
Применение новых возможностей платформы 1С:Предприятие 8.1. Использование временных таблиц.
Одним из основных особенностей платформы 1С: Предприятие 8, является широкое применение механизма запросов для выборки данных. В отличие от версии 7.7, где используется объектная модель получения информации, применение запросов позволяет считывать только необходимые для обработки данные. В отдельных случаях такой подход позволяет повысить производительность приложения в несколько раз. В последних релизах платформы 8.1 появилась возможность использовать в запросах временные таблицы, что позволило повысить эффективность и скорость выполнения запросов и сделать текст сложных запросов более легким для восприятия. В качестве исходных данных для временной таблицы, также может быть использован внешний источник данных: табличная часть документа, таблица значений, результат запроса. В этом случае в запросе нельзя использовать объединения и соединения. Важным условием использования внешних данных является обязательное типизирование полей таблицы значений. Для этих целей отлично подходит приведенная ниже процедура:
Процедура ТипизацияТЗ(ТЗ) Экспорт РезультатТЗ = новый ТаблицаЗначений; Для Каждого Колонка из ТЗ.Колонки Цикл Имя = Колонка.Имя; МассивТипов = новый Массив(1); МассивТипов[0] = ТипЗнч(ТЗ[0][Имя]); Описатель = новый ОписаниеТипов(МассивТипов); РезультатТЗ.Колонки.Добавить(Имя, Описатель); КонецЦикла; Для каждого Строка из ТЗ Цикл СтрокаРез = РезультатТЗ.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаРез, Строка); КонецЦикла; ТЗ = РезультатТЗ.Скопировать(); КонецПроцедуры
В качестве параметра процедуре передается исходная таблица значений. В цикле организован перебор всех колонок и определяется тип данных каждой колонки.
Запрос к обработанной таблице значений может выглядеть так:
ТипизацияТЗ(ТабЗнч); МВТ = НОвый МенеджерВременныхТаблиц; Запрос = Новый запрос; Запрос.МенеджерВременныхТаблиц=МВТ; Запрос.Текст= "ВЫБРАТЬ | ВнешнийИсточник.Документ, | ВнешнийИсточник.Маршрут, | ВнешнийИсточник.Пробег |ПОМЕСТИТЬ ВременнаяТаблица |ИЗ | &ВнешнийИсточник КАК ВнешнийИсточник |; | |//////////////////////////////////////////////////////////////////////////////// |ВЫБРАТЬ | ВременнаяТаблица.Документ, | ВременнаяТаблица.Маршрут КАК Маршрут, | ВременнаяТаблица.Пробег КАК Пробег |ИЗ | ВременнаяТаблица КАК ВременнаяТаблица |ИТОГИ | СУММА(Пробег) |ПО | Маршрут"; Запрос.УстановитьПараметр("ВнешнийИсточник",ТабЗнч);
Первым запросом в пакете мы выбираем данные из таблицы значений и помещаем их во временную таблицу. Вторым запросом формируем группировки по созданной временной таблице. В итоге мы получили ту же таблицу значений, но с рассчитанными итогами по определенным нами группировкам. Надо заметить, что временные таблицы сильно напоминают вложенные запросы и часто возникают вопросы, в каких случаях использовать тот или иной механизм.
Само по себе использование вложенных запросов ничем не ограничивается, однако, соединения с вложенными подзапросами других таблиц базы данных, например, виртуальных таблиц, может сильно затруднить выбор оптимального плана для СУБД. Поэтому высока вероятность ошибки оптимизатора и, соответственно, катастрофического замедления запроса.
Разница в производительности может быть огромной. Например, при выборе правильного плана запрос может работать 1.5 сек, а при выборе неправильного - 18 часов (это реальный случай).
Поэтому следует всегда избегать соединений с вложенными подзапросами. Вместо этого надо использовать временную таблицу.
При использовании временной таблицы запрос будет всегда работать стабильно быстро. Ключевое слово тут - стабильно. Запрос, содержащий соединения с вложенными подзапросами, тоже может иногда работать быстро. Но гарантировать этого нельзя.
Резюмируя можно сказать, что всегда нужно стремиться (с помощью временных таблиц в том числе), делать запрос как можно проще. Избегать вложенных подзапросов, а особенно соединений с ними.