При изучении сложных типовых конфигураций, особенно таких как 1С:ERP Управление предприятием или 1С:Комплексная автоматизация, программисты часто натыкаются на странную конструкцию в запросах: ВЫБРАТЬ ПЕРВЫЕ 9999999999999. На первый взгляд это кажется ошибкой или избыточным кодом, ведь такое число заведомо превышает количество записей в любой таблице. Однако в контексте платформы 1С и работы систем управления базами данных (СУБД) этот "хак" несет в себе глубокий смысл. Разберем детально, какие задачи решает этот прием.
Рассмотрим стандартное поведение платформы 1С. Когда мы пишем запрос на языке запросов 1С, он не передается в СУБД в исходном виде. Платформа транслирует его в "родной" SQL-код (T-SQL для MS SQL Server, PL/pgSQL для PostgreSQL и т.д.).
Существует специфическая особенность: если мы используем предложение УПОРЯДОЧИТЬ ПО (ORDER BY) в запросе, который помещает данные во временную таблицу (ПОМЕСТИТЬ), платформа 1С при трансляции часто просто вырезает сортировку. Логика разработчиков платформы такова: временная таблица — это неупорядоченное множество, и тратить ресурсы сервера на сортировку при вставке бессмысленно, так как порядок при последующей выборке не гарантирован.
Однако программисту часто необходимо, чтобы данные в ВТ лежали в определенном порядке. Использование ключевого слова ПЕРВЫЕ блокирует это автоматическое удаление. Когда транслятор видит ВЫБРАТЬ ПЕРВЫЕ..., он обязан оставить ORDER BY, так как без него выборка "первых" строк лишена смысла. Таким образом, число 999... — это способ заставить платформу оставить сортировку в реальном SQL-запросе.
Проанализируем пример такого запроса из механизмов расчета себестоимости:
ВЫБРАТЬ ПЕРВЫЕ 9999999999999
Т.Регистратор,
Т.Период,
Т.Организация,
Т.Подразделение
ПОМЕСТИТЬ ВТДвиженияТекущейПорции
ИЗ
РегистрНакопления.ВыручкаИПродажиДетально КАК Т
УПОРЯДОЧИТЬ ПО
Т.Регистратор,
Т.Период,
Т.Организация
Выясним, что происходит на стороне СУБД (в частности, Microsoft SQL Server). Когда сервер получает запрос с оператором TOP (аналог ПЕРВЫЕ), включается механизм, называемый Row Goal.
Обычная цель оптимизатора — найти план запроса, который минимизирует общее время выполнения для всего результирующего набора данных (Total Time). Но как только появляется TOP, оптимизатор меняет стратегию: он пытается найти план, который позволит максимально быстро получить первые N строк.
Даже если N — это огромное число 999..., сам факт наличия этого оператора заставляет SQL Server выбирать другие физические операторы соединения. Рассмотрим основные отличия:
Sort в памяти или в tempdb.В сложных расчетах ERP, где пакеты запросов могут содержать сотни таблиц, такая "подсказка" помогает застабилизировать план выполнения, предотвращая ситуации, когда СУБД внезапно выбирает неэффективный метод соединения таблиц из-за ошибки в статистике.
Проанализируем ситуацию с PostgreSQL. В этой СУБД использование LIMIT (аналог ПЕРВЫЕ) при вставке во временную таблицу гарантирует, что база данных выполнит физическую сортировку записей перед их записью. Хотя по канонам реляционной теории порядок записей в таблице не важен, на практике 1С часто использует этот прием для последующего последовательного чтения данных.
Если записи во временной таблице расположены физически последовательно (например, по дате), то последующие запросы, читающие эти данные "порциями", будут работать значительно быстрее за счет уменьшения количества случайных чтений (Random I/O) и более эффективного использования кэша дисковой подсистемы.
Посмотрим на еще одну важную причину. В языке запросов 1С нет полноценной поддержки оконных функций (хотя в последних версиях платформы появилась функция АВТОНОМЕРЗАПИСИ()). До появления штатных средств нумерации, разработчики часто использовали конструкцию ВЫБРАТЬ ПЕРВЫЕ во вложенных запросах для того, чтобы иметь возможность упорядочить данные перед их обработкой в коде или перед использованием в соединениях, где порядок критичен для логики алгоритма.
Если в запросе требуется использовать УПОРЯДОЧИТЬ ПО во вложенном запросе, 1С выдаст ошибку синтаксиса, если не будет указано ПЕРВЫЕ. Поэтому использование огромного числа становится единственным выходом, чтобы запрос прошел проверку синтаксиса и сохранил логику сортировки.
Использование ВЫБРАТЬ ПЕРВЫЕ 9999999999999 — это мощный инструмент "тонкой настройки" запросов. Мы применяем его, когда:
УПОРЯДОЧИТЬ ПО во вложенных конструкциях.Несмотря на то что это выглядит как "костыль", в высоконагруженных системах типа ERP этот прием позволяет добиться стабильности и высокой скорости расчета себестоимости, предотвращая непредсказуемое поведение оптимизаторов СУБД на больших объемах данных.