При работе с несколькими экземплярами одной и той же информационной базы — например, с рабочей базой и её копией для разработки — специалисты часто замечают странную особенность: при одинаковых настройках и идентичных конфигурациях данные в списках документов, регистрах или консоли запросов выводятся в разном порядке. Рассмотрим детально, почему это происходит, как на это влияет архитектура систем управления базами данных (СУБД) и где искать настройки, управляющие этим поведением.
Первое и самое важное правило, которое нам необходимо усвоить: если в тексте запроса явно не указано предложение УПОРЯДОЧИТЬ ПО, СУБД (будь то Microsoft SQL Server или PostgreSQL) не гарантирует никакой последовательности выдачи строк. Проанализируем ситуацию: когда мы выполняем запрос в консоли, система возвращает записи в том порядке, в котором ей было «удобнее» их прочитать в данный конкретный момент.
Разберем пример простого запроса к регистру накопления:
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Количество,
Продажи.Сумма
ИЗ
РегистрНакопления.Продажи КАК Продажи
В этом случае в одной базе записи могут выстроиться по дате, во второй — по внутреннему идентификатору, а в третьей — в порядке физического добавления в таблицу. Чтобы результат был всегда одинаковым, мы должны всегда использовать явную сортировку:
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Количество,
Продажи.Сумма
ИЗ
РегистрНакопления.Продажи КАК Продажи
УПОРЯДОЧИТЬ ПО
Продажи.Период,
Продажи.Регистратор
Если различие в порядке наблюдается не в консоли запросов, а в стандартных формах списков (например, при открытии движений документа или списка справочника), причину следует искать в настройках пользовательского интерфейса. Платформа 1С сохраняет настройки каждого пользователя индивидуально.
Выясним причину, заглянув в настройки формы. Часто пользователи случайно нажимают на заголовок колонки, устанавливая ручную сортировку. В этом случае над названием колонки появляется небольшая стрелка (вверх или вниз). Проанализируем шаги для исправления ситуации:
Когда мы работаем с клиент-серверным вариантом базы, порядок выдачи данных без ORDER BY зависит от физического состояния таблиц в СУБД. Рассмотрим, как это работает в разных системах.
В MS SQL Server данные часто выдаются в порядке так называемого кластерного индекса (обычно это первичный ключ таблицы). Однако, если в одной базе недавно проводилась дефрагментация или перестроение индексов, а в другой — нет, физическое расположение страниц данных на диске будет отличаться. Это приведет к тому, что SQL Server вернет строки в разной последовательности при простом сканировании таблицы.
В PostgreSQL ситуация еще интереснее. Эта СУБД часто возвращает записи в порядке их «физического» расположения в файле (параметр CTID). Если в одной базе запись была обновлена (UPDATE), PostgreSQL фактически помечает старую версию записи как удаленную и записывает новую в конец файла. Таким образом, обновленная запись «переезжает» в конец выборки, в то время как в другой базе, где обновления не было, она остается на прежнем месте.
Проанализируем ситуацию, когда данные упорядочены по строковому полю, но их порядок все равно различается (например, в одной базе «ё» идет после «е», а в другой — в конце алфавита). Это напрямую связано с настройкой Collation на уровне СУБД или самой базы данных.
Если при установке SQL Server в одной базе была выбрана сортировка Cyrillic_General_CI_AS (регистронезависимая), а в другой — Cyrillic_General_BIN (бинарная), то алгоритмы сравнения строк будут работать по-разному. Бинарная сортировка расставляет символы строго по их кодам, что приводит к иному порядку строк с заглавными и строчными буквами, а также спецсимволами.
В регистрах 1С существуют скрытые или системные поля, которые влияют на последовательность записей. Посмотрим на пример регистра накопления. Даже если документы проведены одной секундой, платформа 1С обеспечивает их уникальную последовательность с помощью механизма Момента времени, который включает в себя дату и ссылку на регистратор.
Для записей внутри одного документа критически важным является поле _LineNo (номер строки). Если в одной из баз движения документа формировались или корректировались программно без корректного заполнения номеров строк или с их нарушением, порядок вывода в списках может стать непредсказуемым. Также стоит обратить внимание на техническое поле KeyField (или _KeyField в SQL), которое используется платформой для идентификации уникальных записей в наборах данных. Любое ручное или программное редактирование движений, обходящее стандартные механизмы проведения, может нарушить естественный порядок этих полей.
Выясним, почему даже один и тот же запрос может возвращать данные по-разному при большой нагрузке. Оптимизатор СУБД строит «план выполнения запроса» на основе статистики. Если в базах разный объем данных (даже если они визуально похожи), СУБД может решить считывать данные параллельно в несколько потоков (параметр MAXDOP в SQL Server). В этом случае итоговый результат формируется из фрагментов, которые считались быстрее других. Без явной сортировки итоговый набор строк будет зависеть от того, какой процессорный поток закончил работу первым.
Чтобы привести порядок следования данных к единому виду в разных базах, выполним следующие рекомендации:
УПОРЯДОЧИТЬ ПО в текстах запросов. Это единственный способ гарантировать результат.Collation баз данных в SQL-сервере совпадали.Таким образом, различие в порядке следования — это не ошибка, а естественное поведение реляционных баз данных и гибкость интерфейса 1С. Понимая эти механизмы, мы можем легко управлять отображением информации и избегать путаницы при сравнении данных в разных системах.