Применение новых возможностей платформы 1С:Предприятие 8.1. Использование временных таблиц.

Одним из основных особенностей платформы 1С: Предприятие 8, является широкое применение механизма запросов для выборки данных. В отличие от версии 7.7, где используется объектная модель получения информации, применение запросов позволяет считывать только необходимые для обработки данные. В отдельных случаях такой подход позволяет повысить производительность приложения в несколько раз. В последних релизах платформы 8.1 появилась возможность использовать в запросах временные таблицы, что позволило повысить эффективность и скорость выполнения запросов и сделать текст сложных запросов более легким для восприятия. В качестве исходных данных для временной таблицы, также может быть использован внешний источник данных: табличная часть документа, таблица значений, результат запроса. В этом случае в запросе нельзя использовать объединения и соединения. Важным условием использования внешних данных является обязательное типизирование полей таблицы значений. Для этих целей отлично подходит приведенная ниже процедура:


Процедура ТипизацияТЗ(ТЗ) Экспорт
РезультатТЗ = новый ТаблицаЗначений;
Для Каждого Колонка из ТЗ.Колонки Цикл
Имя = Колонка.Имя;
МассивТипов = новый Массив(1);
МассивТипов[0] = ТипЗнч(ТЗ[0][Имя]);
Описатель = новый ОписаниеТипов(МассивТипов);
РезультатТЗ.Колонки.Добавить(Имя, Описатель);
КонецЦикла;
Для каждого Строка из ТЗ Цикл
СтрокаРез = РезультатТЗ.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаРез, Строка);
КонецЦикла;
ТЗ = РезультатТЗ.Скопировать();
КонецПроцедуры

В качестве параметра процедуре передается исходная таблица значений. В цикле организован перебор всех колонок и определяется тип данных каждой колонки.

Запрос к обработанной таблице значений может выглядеть так:


ТипизацияТЗ(ТабЗнч);
МВТ = НОвый МенеджерВременныхТаблиц;
Запрос = Новый запрос;
Запрос.МенеджерВременныхТаблиц=МВТ;
Запрос.Текст=
"ВЫБРАТЬ
| ВнешнийИсточник.Документ,
| ВнешнийИсточник.Маршрут,
| ВнешнийИсточник.Пробег
|ПОМЕСТИТЬ ВременнаяТаблица
|ИЗ
| &ВнешнийИсточник КАК ВнешнийИсточник
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВременнаяТаблица.Документ,
| ВременнаяТаблица.Маршрут КАК Маршрут,
| ВременнаяТаблица.Пробег КАК Пробег
|ИЗ
| ВременнаяТаблица КАК ВременнаяТаблица
|ИТОГИ
| СУММА(Пробег)
|ПО
| Маршрут";
Запрос.УстановитьПараметр("ВнешнийИсточник",ТабЗнч);

Первым запросом в пакете мы выбираем данные из таблицы значений и помещаем их во временную таблицу. Вторым запросом формируем группировки по созданной временной таблице. В итоге мы получили ту же таблицу значений, но с рассчитанными итогами по определенным нами группировкам. Надо заметить, что временные таблицы сильно напоминают вложенные запросы и часто возникают вопросы, в каких случаях использовать тот или иной механизм.

Само по себе использование вложенных запросов ничем не ограничивается, однако, соединения с вложенными подзапросами других таблиц базы данных, например, виртуальных таблиц, может сильно затруднить выбор оптимального плана для СУБД. Поэтому высока вероятность ошибки оптимизатора и, соответственно, катастрофического замедления запроса.

Разница в производительности может быть огромной. Например, при выборе правильного плана запрос может работать 1.5 сек, а при выборе неправильного - 18 часов (это реальный случай).

Поэтому следует всегда избегать соединений с вложенными подзапросами. Вместо этого надо использовать временную таблицу.

При использовании временной таблицы запрос будет всегда работать стабильно быстро. Ключевое слово тут - стабильно. Запрос, содержащий соединения с вложенными подзапросами, тоже может иногда работать быстро. Но гарантировать этого нельзя.

Резюмируя можно сказать, что всегда нужно стремиться (с помощью временных таблиц в том числе), делать запрос как можно проще. Избегать вложенных подзапросов, а особенно соединений с ними.