Что быстрее в 1С: временная таблица в запросе или индексированная таблица значений?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Вопрос выбора между использованием Таблицы Значений (ТЗ) и Временной Таблицы (ВТ) в среде 1С:Предприятие является фундаментальным для оптимизации производительности системы. На первый взгляд может показаться, что работа с данными в оперативной памяти (ТЗ) всегда быстрее, чем обращение к СУБД. Однако, как показывает практика и детальный разбор механизмов платформы, ответ зависит от множества факторов: объема данных, сложности алгоритма и накладных расходов на передачу информации между сервером приложений и сервером баз данных.

В этой статье мы подробно проанализируем, в каких ситуациях стоит отдать предпочтение конкретному инструменту, разберем технические нюансы работы MS SQL и памяти сервера 1С, а также рассмотрим практические примеры кода.

Механика работы Таблицы Значений в памяти сервера

Когда мы работаем с объектом ТаблицаЗначений на стороне сервера приложений, данные располагаются в оперативной памяти рабочего процесса rphost. Рассмотрим особенности этого подхода:

  1. Отсутствие сетевых задержек: При выполнении поиска или обхода ТЗ серверу 1С не нужно обращаться к SQL-серверу. Это исключает так называемый "round-trip" (время на отправку запроса и получение ответа), который даже при расположении СУБД на том же компьютере занимает определенное время.
  2. Индексация в памяти: Если для ТаблицыЗначений построены индексы (с помощью метода Индексы.Добавить()), поиск по ней происходит чрезвычайно быстро. Платформа использует хэш-таблицы, что обеспечивает практически мгновенный доступ к нужной строке по ключу.
  3. Затраты памяти: Основной минус ТЗ — потребление оперативной памяти. На очень больших объемах (сотни тысяч и миллионы строк) объект ТаблицаЗначений может разрастись до нескольких гигабайт, что способно вызвать деградацию всей системы или аварийное завершение процесса rphost.

Механика работы Временных Таблиц в СУБД

Временные таблицы создаются в базе данных tempdb на стороне SQL-сервера. Рассмотрим, что происходит "под капотом", когда мы помещаем ТЗ во временную таблицу:

Проанализируем процесс маршалинга: при выполнении запроса на помещение данных из ТЗ во временную таблицу, сервер приложений 1С формирует пакет данных (часто в виде инструкций INSERT INTO или аналогичных механизмов быстрой загрузки) и передает их SQL-серверу. Это само по себе является затратной операцией по времени.

Однако у ВТ есть неоспоримые преимущества:

  1. Мощность SQL: Если после наполнения временной таблицы нам нужно выполнить сложное соединение (JOIN) с физическими таблицами БД (например, с остатками или справочниками), SQL-сервер сделает это на порядки быстрее, чем если бы мы выгружали миллионы строк из БД в 1С и пытались "склеить" их в ТЗ.
  2. Кэширование: MS SQL эффективно кэширует данные временных таблиц в памяти, а также строит оптимальные планы выполнения запросов.
  3. Параллелизм: SQL-сервер может выполнять сложные операции над временными таблицами параллельно, задействуя несколько ядер процессора.

Проблема запросов в цикле: ТЗ против ВТ

Выясним причину, почему программисты часто спорят о "запросах в цикле" применительно к временным таблицам. Разберем ситуацию на примере получения цен для списка товаров.

Рассмотрим пример кода, где поиск осуществляется запросом к временной таблице внутри цикла (традиционно плохая практика):


// Предположим, ВТ_ТЗ уже создана и наполнена данными
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МойМенеджерВТ;

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

Почему это медленно? Несмотря на то, что данные лежат во временной таблице, каждый вызов Запрос.Выполнить() заставляет сервер приложений 1С инициировать сеанс связи с SQL-сервером. Накладные расходы на саму инициализацию запроса (parse, compile, execute) могут превышать время поиска данных в сотни раз. В 1С отсутствует полноценный механизм Prepare/Execute для таких случаев, поэтому каждое выполнение — это "тяжелая" операция.

Как сделать правильно? Вместо цикла по ВТ следует выполнить одно соединение временной таблицы с основной таблицей данных или просто выгрузить результат в индексированную ТЗ один раз.

Сравнительный анализ: когда и что выбирать

Проанализируем примерные пороги эффективности, выведенные на основе практического опыта разработчиков:

Подробное решение: Оптимальный алгоритм сопоставления данных

Разберем по шагам, как эффективно решить задачу сопоставления данных из внешнего источника (например, Excel) с данными в базе 1С, используя синергию ТЗ и запросов.

Шаг 1. Подготовка данных в ТЗ

Сначала мы загружаем данные в ТаблицуЗначений. Обязательно типизируем колонки, чтобы избежать проблем при передаче в запрос.

Шаг 2. Помещение во временную таблицу

Вместо того чтобы искать данные по одному, мы передаем всю таблицу в запрос целиком.


МенеджерВТ = Новый МенеджерВременныхТаблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

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

Запрос.УстановитьПараметр("ВнешняяТЗ", МояТаблицаЗначений);
Запрос.УстановитьПараметр("Период", ТекущаяДата());

РезультатЗапроса = Запрос.Выполнить().Выгрузить();

Что мы получили? Мы совершили всего ОДНО обращение к СУБД. Платформа 1С сама сформировала оптимальный способ передачи ТЗ на сервер SQL, а SQL-сервер выполнил соединение с физической таблицей цен максимально эффективно. Это в десятки раз быстрее, чем перебор ТЗ в цикле с выполнением запросов к ценам для каждой строки.

Резюме

Проанализировав ситуацию, можно сделать следующие выводы:

  1. Таблица Значений — это идеальный инструмент для кратковременного хранения и быстрого поиска в памяти небольших и средних объемов данных (до 10-20 тысяч строк), особенно если не требуется соединение с данными из БД.
  2. Временная Таблица — незаменима при работе с большими массивами данных и в случаях, когда данные из внешнего источника нужно объединить с данными таблиц 1С (справочники, регистры).
  3. Главный враг производительности — не выбор между ТЗ или ВТ, а архитектурные ошибки, такие как запросы в цикле. Всегда стремитесь к тому, чтобы минимизировать количество обращений "сервер 1С — сервер SQL", объединяя операции в пакетные запросы.

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

← На главную