В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с выбором: использовать вложенные запросы или временные таблицы. Эффективная работа с данными напрямую зависит от того, насколько грамотно структурирован запрос. В этой статье мы подробно разберем, как работать с МенеджеромВременныхТаблиц, проанализируем ситуации, в которых временные таблицы незаменимы, и научимся оптимизировать их использование для достижения максимальной скорости выполнения кода.
Разберем ситуацию: когда вложенный запрос выполняется несколько раз или содержит большой объем данных, СУБД (например, MS SQL Server или PostgreSQL) может некорректно построить план запроса. Это приводит к значительному замедлению работы системы. Рассмотрим основные преимущества использования временных таблиц:
Для работы с временными таблицами нам необходимо создать объект МенеджерВременныхТаблиц и связать его с объектом Запрос. Рассмотрим пример кода, в котором мы подготавливаем данные о продажах для дальнейшего анализа:
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст =
"ВЫБРАТЬ
| ПродажиОбороты.Номенклатура КАК Номенклатура,
| ПродажиОбороты.КоличествоОборот КАК Количество
|ПОМЕСТИТЬ ВТ_Продажи
|ИЗ
| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода) КАК ПродажиОбороты
|ИНДЕКСИРОВАТЬ ПО
| Номенклатура";
Запрос.Выполнить();
В данном примере мы используем ключевое слово ПОМЕСТИТЬ, которое указывает системе, что результат запроса не нужно выгружать в выборку, а следует сохранить во временной таблице с именем ВТ_Продажи. Обратите внимание на конструкцию ИНДЕКСИРОВАТЬ ПО. Проанализируем её важность: индексация по полю связи позволяет СУБД мгновенно находить нужные строки при последующем соединении этой таблицы с другими данными.
Зачастую одной таблицы недостаточно. Разберем по шагам создание пакета запросов, где данные из первой временной таблицы используются во второй. Это стандартная практика для сложных отчетов и механизмов проведения документов.
Запрос.Текст =
"ВЫБРАТЬ
| ВТ_Продажи.Номенклатура,
| ВТ_Продажи.Количество
|ПОМЕСТИТЬ ВТ_Фильтр
|ИЗ
| ВТ_Продажи КАК ВТ_Продажи
|ГДЕ
| ВТ_Продажи.Количество > 10
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_Фильтр.Номенклатура,
| ЦеныНоменклатурыСрезПоследних.Цена
|ИЗ
| ВТ_Фильтр КАК ВТ_Фильтр
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК ЦеныНоменклатурыСрезПоследних
| ПО ВТ_Фильтр.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура";
РезультатЗапроса = Запрос.Выполнить();
Выясним причину использования точки с запятой ;. Она разделяет отдельные запросы внутри одного пакета. Проанализируем ситуацию: в первом запросе мы отфильтровали данные и поместили их в ВТ_Фильтр, а во втором — соединили полученный результат с регистром цен. Это гораздо эффективнее, чем пытаться наложить условия и соединения в одном огромном запросе.
Многие программисты забывают, что временные таблицы занимают место в оперативной памяти сервера 1С и в базе tempdb на стороне СУБД. Если мы создаем таблицы в цикле или внутри часто вызываемых процедур, это может привести к переполнению ресурсов. Рассмотрим, как правильно уничтожать таблицы.
Существует два способа очистки:
МенеджерВременныхТаблиц (когда переменная выходит из области видимости).УНИЧТОЖИТЬ в тексте запроса. Это предпочтительный метод, если таблица больше не нужна в рамках текущего пакета.Пример явного уничтожения таблицы:
Запрос.Текст = "УНИЧТОЖИТЬ ВТ_Продажи";
Запрос.Выполнить();
Рекомендуем всегда уничтожать промежуточные таблицы, если ваш пакет запросов состоит из 10 и более шагов. Это позволяет поддерживать производительность системы на высоком уровне.
Проанализируем основные промахи, которые могут свести на нет всю пользу от оптимизации:
РегистрБухгалтерии) и не проиндексировали поля связи во временной таблице, запрос может работать медленнее, чем обычный вложенный запрос.tempdb.Посмотрим на дополнительные возможности. В 1С 8.3 появилась возможность передавать временные таблицы между разными объектами Запрос, если они используют один и тот же МенеджерВременныхТаблиц. Это позволяет выстраивать сложную цепочку вычислений, разбитую на разные модули и функции.
Также важно помнить про типизацию. Платформа 1С определяет типы полей временной таблицы автоматически на основе первого запроса. Если вы планируете использовать таблицу для объединения с другими данными, убедитесь, что типы полей строго определены (используйте ВЫРАЗИТЬ, если поле может содержать составной тип).
Разберем пример с явным приведением типов:
Запрос.Текст =
"ВЫБРАТЬ
| ВЫРАЗИТЬ(ДокументОснование КАК Документ.РеализацияТоваровУслуг) КАК Ссылка,
| СуммаДокумента КАК Сумма
|ПОМЕСТИТЬ ВТ_Данные
|ИЗ
| Документ.ЗаказПокупателя";
В этом случае мы гарантируем, что в колонке Ссылка будут данные только одного типа, что значительно ускорит индексацию и последующие соединения на уровне SQL-сервера.
Подводя итог, можно сказать, что временные таблицы — это мощный инструмент в руках разработчика 1С. Правильное их применение, включающее индексацию, своевременное уничтожение и грамотное разделение логики на пакеты, позволяет кратно увеличить скорость работы конфигурации и обеспечить стабильность системы при работе с большими объемами данных.