При разработке сложных механизмов обработки данных в 1С:Предприятие часто возникает вопрос о производительности запросов, особенно когда в них передаются большие объемы данных через ТаблицаЗначений. Давайте вместе разберем, что происходит с индексами при передаче данных в запрос и как правильно управлять индексацией в процессе выполнения кода.
Многие разработчики ошибочно полагают, что если в ТаблицаЗначений были программно добавлены индексы через метод Индексы.Добавить(), то при передаче этой таблицы в качестве параметра запроса эти индексы сохранятся во временной таблице. Спешим развеять этот миф: индексы не переносятся.
Когда мы передаем ТаблицаЗначений в запрос, платформа выполняет сериализацию данных. По сути, данные «переливаются» из оперативной памяти в структуру временной таблицы (ВТ) внутри контекста запроса. Эта временная таблица создается как абсолютно новая сущность с «чистого листа». У нее нет никаких индексов, независимо от того, как была настроена исходная таблица в коде 1С.
Важно понимать фундаментальное различие: ТаблицаЗначений — это объектный тип данных, существующий в оперативной памяти сервера 1С, тогда как временная таблица запроса — это механизм СУБД или внутреннего движка запросов 1С. Они работают по разным правилам.
В момент создания временной таблицы в запросе через конструкцию ПОМЕСТИТЬ система не анализирует структуру индексов источника, так как запрос оперирует на уровне описания своей структуры в тексте. Если вам нужна производительность, которую дает индекс, вы должны явно заявить об этом в тексте запроса.
Разберем, как создать временную таблицу с индексами. Для этого в языке запросов 1С предусмотрена специальная конструкция ИНДЕКСИРОВАТЬ ПО. Рассмотрим пример того, как это реализуется:
ВЫБРАТЬ
ТЗ.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_Данные
ИЗ
&ТЗ КАК ТЗ
ИНДЕКСИРОВАТЬ ПО
Ссылка
;
ВЫБРАТЬ
ВТ.Ссылка
ИЗ
ВТ_Данные КАК ВТ
Добавляя инструкцию ИНДЕКСИРОВАТЬ ПО, вы даете платформе команду создать индекс по указанным полям непосредственно во временной таблице. Это критически важно при соединении (ЛЕВОЕ СОЕДИНЕНИЕ, ВНУТРЕННЕЕ СОЕДИНЕНИЕ) этой таблицы с другими большими наборами данных.
Часто задают вопрос: если запрос вернул результат в ТаблицаЗначений, будут ли у этой результирующей таблицы индексы? Ответ — нет. Метод Выгрузить() создает обычную «плоскую» ТаблицаЗначений без каких-либо установленных индексов.
Если после выполнения запроса вам необходимо продолжать интенсивно работать с полученными данными, выполняя поиск методом НайтиСтроки() или Найти(), вам придется создавать индексы вручную программным способом:
РезультатЗапроса = Запрос.Выполнить();
ТЗРезультат = РезультатЗапроса.Выгрузить();
ТЗРезультат.Индексы.Добавить(\"Ссылка\");
Проанализируем необходимость индексации. В вашем примере (10 000 и 5 000 записей) использование индексов может не дать ощутимого прироста скорости, так как накладные расходы на создание индекса могут превысить время самого соединения таблиц. Индексацию внутри запроса стоит применять в следующих случаях:
JOIN) внутри одного сложного запроса.Подводя итог, запомните: при передаче ТаблицаЗначений в запрос индексы всегда теряются, временные таблицы в запросе требуют явного указания ИНДЕКСИРОВАТЬ ПО, а результат запроса всегда возвращается без индексов. Управляйте индексацией осознанно, ориентируясь на объемы данных в вашей задаче.