← вся теориятеория к собесу · Оптимизация запросов 1С

Как запрос 1С становится SQL

разбор писал Даниил, автор Сеньорчика

Зачем это спрашивают

Запрос на языке 1С не выполняется сам по себе: сервер 1С переводит его в один или несколько SQL-запросов, и выполняет их СУБД (система управления базами данных). Чтобы разбирать медленные запросы, нужно знать, как объекты 1С лежат в базе и где увидеть настоящий SQL. На собесе мидла и сеньора это спрашивают почти всегда.

// Так спрашивают: «Как называются таблицы 1С в СУБД?» «Как найти таблицу регистра в базе?» «Как хранится составной реквизит?» «Где увидеть SQL, который выполнила СУБД?»

Таблицы и поля

В СУБД нет таблицы «Номенклатура». Объекты конфигурации лежат в таблицах со служебными именами, а реквизиты в полях с номерами. Номера свои в каждой базе:

Соответствие имён даёт функция ПолучитьСтруктуруХраненияБазыДанных(): она возвращает таблицу, где для каждого объекта метаданных указаны имя таблицы и имена полей в СУБД. Это первый шаг при разборе плана запроса.

Структура = ПолучитьСтруктуруХраненияБазыДанных(
    ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Метаданные.РегистрыНакопления.ТоварыНаСкладах), Истина);
Для Каждого Таблица Из Структура Цикл
    Сообщить(Таблица.ИмяТаблицыХранения + " = " + Таблица.ИмяТаблицы);
КонецЦикла;

Составные поля

Составной реквизит хранится не одним полем, а несколькими колонками: тип значения, число, строка, дата, тип ссылки и сама ссылка. Поле Регистратор регистра, который пишут десять видов документов, хранится как _RecorderTRef с номером типа и _RecorderRRef со ссылкой.

Отсюда цена разыменования составного поля: чтобы прочитать Регистратор.Дата, СУБД соединяет таблицу с каждой таблицей документов, номер которой может оказаться в _RecorderTRef.

Виртуальные таблицы и журнал

Виртуальная таблица раскрывается в подзапросы и временные таблицы. В MS SQL их видно как #tt в tempdb, в PostgreSQL как временные таблицы tt. Запрос остатков на дату превращается в чтение итогов и сложение с движениями между итогом и датой.

Настоящий SQL видно в технологическом журнале: события DBMSSQL для MS SQL и DBPOSTGRS для PostgreSQL содержат текст запроса к СУБД и его длительность, а событие SDBL показывает запрос на языке 1С. По ним связывают медленный SQL с местом в коде.

Под администратором с полными правами условий ограничения доступа в SQL нет. Медленный запрос пользователя с ограничением доступа на уровне записей (RLS, row level security) воспроизводят под его ролями, иначе проблема не повторится.

Как отвечать: «Как найдёшь в СУБД таблицу регистра ТоварыНаСкладах?»

Вызову ПолучитьСтруктуруХраненияБазыДанных для этого регистра: она вернёт имена таблиц хранения, например _AccumRg89 для движений и _AccumRgT90 для итогов, и имена полей для каждого измерения и ресурса. Номера в каждой базе свои, поэтому по памяти их не называю. Дальше по этим именам ищу запросы в технологическом журнале и смотрю план в СУБД.

Кандидат знает инструмент, называет формат имён и понимает, что номера зависят от базы. Связка со следующим шагом разбора показывает практику.

На чём валят

  • −Ищут проблему ограничения доступа под администратором. У полных прав условий RLS в SQL нет. Воспроизводят под ролями пользователя.
  • −Вклеивают значения в текст запроса. Каждый вызов даёт новый текст и новый план. Значения передают параметрами.
  • −Создают индексы в СУБД руками. Реструктуризация их удалит. Индексы задают метаданными.
  • −Ищут таблицу по имени объекта в СУБД. Имена служебные. Соответствие даёт ПолучитьСтруктуруХраненияБазыДанных().

Проверь себя

Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.

  1. #oc_q_to_sql1 / 5
    Какой метод сопоставляет объекты конфигурации с таблицами и полями СУБД?
    A)Метаданные.ТаблицыСУБД()
    B)ОбщегоНазначения.ИмяТаблицы()
    C)ПолучитьСтруктуруХраненияБазыДанных()
    D)ПолучитьИмяТаблицы(Метаданные)
    показать ответ и разбор
    +C)`ПолучитьСтруктуруХраненияБазыДанных()`

    // разбор: ПолучитьСтруктуруХраненияБазыДанных() возвращает таблицу соответствия: объект метаданных, его таблицы СУБД, поля и индексы. Её используют, чтобы разобрать запрос из технологического журнала или журнала СУБД и понять, какой регистр тормозит.

  2. #oc_q_to_sql2 / 5
    Как хранится в СУБД реквизит составного типа (Строка, Число, СправочникСсылка.Контрагенты)?
    A)Одной текстовой колонкой с сериализованным значением
    B)Несколькими колонками: тип, число, строка, ссылка
    C)Одной двоичной колонкой ссылки
    D)Отдельной таблицей значений
    показать ответ и разбор
    +B)Несколькими колонками: тип, число, строка, ссылка

    // разбор: Для составного типа платформа заводит колонку-признак типа (_TYPE) и по колонке на каждый вид значения: _N для чисел, _S для строк, _RTRef и _RRRef для ссылок (тип и значение). Отсюда цена составных типов: шире строки, сложнее индексы и условия в SQL.

  3. #oc_q_to_sql3 / 5
    Один запрос 1С с двумя виртуальными таблицами в техжурнале превратился в несколько SQL-запросов. Почему?
    A)Техжурнал дублирует записи о запросах
    B)Таблицы раскрываются в подзапросы
    C)Платформа делит запрос по одному на поле
    D)Платформа выполняет каждую строку отдельно
    показать ответ и разбор
    +B)Таблицы раскрываются в подзапросы

    // разбор: Виртуальная таблица — параметризованный запрос к итогам и движениям. При трансляции платформа может создать временные таблицы (#tt в MS SQL) и несколько SQL-запросов, чтобы получить остатки, а затем соединить их. Поэтому один «простой» запрос 1С иногда дорогой для СУБД.

  4. #oc_q_to_sql4 / 5
    В каком событии технологического журнала видны SQL-тексты запросов к MS SQL?
    A)DBMSSQL
    B)EXCP
    C)TLOCK
    D)CALL
    показать ответ и разбор
    +A)`DBMSSQL`

    // разбор: DBMSSQL фиксирует обращения к MS SQL Server с текстом запроса, длительностью и, при настройке, планом. Для PostgreSQL событие называется DBPOSTGRS. CALL — серверные вызовы, EXCP — исключения, TLOCK — управляемые блокировки.

  5. #oc_q_to_sql5 / 5
    Почему запрос, который в файловой базе работал мгновенно, в клиент-серверной на MS SQL тормозит?
    A)На клиенте: запросы выполняет клиент
    B)MS SQL не поддерживает виртуальные таблицы 1С
    C)Файловая база кэширует всё в памяти
    D)План строит СУБД по статистике
    показать ответ и разбор
    +D)План строит СУБД по статистике

    // разбор: В файловом варианте данные обычно маленькие, и любой план быстр. В клиент-серверной базе оптимизатор СУБД выбирает план по статистике и индексам, и на больших таблицах неудачное условие даёт полный просмотр. Устаревшая статистика — частая причина внезапного замедления.

дальше

Теорию прочитал. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, бесплатная часть практики — одна сессия дня в сутки.