Что делает "В ИЕРАРХИИ" в запросе?

Публикация № 1091745

Программирование - Теория программирования

запросы в иерархии производительность платформа внутренние механизмы

80
Описание действий платформы 1С при использовании конструкции "В ИЕРАРХИИ" в запросах.

Начало

Конструкция "В ИЕРАРХИИ" в запросах позволяет получить подчиненные элементы иерархического объекта конфигурации по заданному отбору. Это может быть иерархический справочник, план счетов, план видов характеристик и др. Сегодня в статье рассмотрим пример использования, а также действия платформы на стороне СУБД, влияние на производительность.

Статья имеет больше обзорный характер. Главная цель - продемонстрировать принцип работы этой инструкции, чтобы точно понимать когда ее стоит использовать, а когда нет.

Использование

Рассмотрим простой пример использования конструкции "В ИЕРАРХИИ". При выполнении следующего запроса будут получены подчиненные элементы иерархического справочника "Товары" для переданного значения параметра "Ссылка".

ТекстЗапроса = 
"ВЫБРАТЬ
| Товары.Ссылка,
| Товары.Артикул
|ИЗ
| Справочник.Товары КАК Товары
|ГДЕ
| Товары.Ссылка В ИЕРАРХИИ(&Ссылка)"

В качестве значения параметра "Ссылка" передается ссылка на группу справочника. Пример выполняем на "самописной" тестовой базе, но структура справочника "Номенклатура" очень напоминает урезанную версию из типовых конфигураций. Справочник содержит следующие данные:

Конечно, на изображении показаны не все записи справочника. Скриншот показывает лишь структуру хранения данных в иерархическом справочнике. В таблице хранятся 10 групп верхнего уровня, в каждой из них содержится 5 вложенных групп с 200 элементами в каждой.

Вернемся к тестовому запросу. Передадим в параметр "Ссылка" ссылку на группу "Группа - 1" (см. скриншот выше). Тогда результат выполнения запроса будет выглядеть следующим образом:

Как мы видим, запрос вернул ссылку на саму верхнюю группу (переданную параметром), а также вложенные группы с находящимися в них элементами. Таким образом, использование конструкции "В ИЕРАРХИИ" позволяет удобным образом получать иерархически подчиненные данные. 

Синтаксис языка запросов 1C:Предприятия и классического SQL очень похожи во многих моментах. Но для выражения "В ИЕРАРХИИ" нет аналога в языке запросов SQL как, например, для выражения языка запросов платформы "В" есть аналогичный SQL-оператор "IN". Поэтому интересной является работа платформы с СУБД при использовании данного оператора.

За кулисами

Итак, приступим. Для примера будем использовать написанный ранее запрос к справочнику "Товары". Анализировать действия платформы будем для ситуации, когда в качестве параметра передана группа верхнего уровня "Группа 1", что мы уже сделали ранее.

Теперь по порядку. В первом случае платформа выполнит следующие действия на SQL-сервере:

1. Сначала выполняется запрос на получение ссылки на группу справочника, переданную в качестве параметра, и всех подчиненных ей групп и элементов. Результат помещается во временную таблицу '#tt1'.

2. На втором этапе дважды выполняется запрос:

На скриншоте подробно прокомментирован текст SQL-запроса. Если кратко, то запрос позволяет выбрать подчиненные элементы для групп, ссылки на которые находятся во временной таблице. Остается вопрос: "Зачем запрос выполняется дважды?". Тут ответ простой: сначала запрос получает подчиненные элементы для групп первого уровня, которые уже содержатся во временной таблице (см. пункт 1). Затем второй запрос получает подчиненные элементы для подчиненных групп второго уровня. Поскольку на третьем уровне иерархии не присутствует ни одна группа справочника, то данный запрос более не выполняется.

В нашем случае, второй запрос вернет пустой результат, так как для записей, находящихся на 3-м уровне иерархии, нет подчиненных элементов (там нет ни одной группы). 

3. Для получения конечного результата платформа формирует следующий SQL-запрос:

Результат именно этого запроса в дальнейшем может обрабатываться алгоритмами на встроенном языке платформы. Таким образом, записи во временной таблице '#tt1' используются для установки условия выборки из таблицы справочника "_Reference41".

4. На последнем шаге платформа очищает и удаляет временную таблицу '#tt1', поскольку в дальнейшем она уже не будет использоваться.

Пример посложнее

Рассмотрим пример посложнее, чем простой запрос к справочнику. Допустим, у нас есть запрос к регистру бухгалтерии "Хозрасчетный".

ВЫБРАТЬ
	ХозрасчетныйОстатки.Организация КАК Организация,
	ХозрасчетныйОстатки.Валюта КАК Валюта,
	ХозрасчетныйОстатки.Подразделение КАК Подразделение,
	ХозрасчетныйОстатки.Счет КАК Счет,
	ХозрасчетныйОстатки.Субконто1 КАК Субконто1,
	ХозрасчетныйОстатки.Субконто2 КАК Субконто2,
	ХозрасчетныйОстатки.Субконто3 КАК Субконто3,
	ХозрасчетныйОстатки.СуммаОстаток КАК СуммаОстаток
ИЗ
	РегистрБухгалтерии.Хозрасчетный.Остатки(, Счет В ИЕРАРХИИ (&Счет), , ) КАК ХозрасчетныйОстатки

Условие по счету установлены с помощью инструкции "В ИЕРАРХИИ" по значению "10". На сервере СУБД платформа выполнит ряд запросов.

 
 Запросы платформы при использовании "В ИЕРАРХИИ"

Таким образом, инструкция "В ИЕРАРХИИ" работает практически во всех случаях одинаково в несколько этапов:

  1. Получаем ссылку на текущий элемент и подчиненные ему элементы.
  2. В несколько запросов получает элементы для всех последующих уровней иерархии.
  3. Полученные данные используются в последующих запросах платформы. Как они будут использоваться сильно зависит от конкретного запроса в конфигурации (запрос к справочнику, виртуальным таблицам и др.).

Вроде, все не так уж и сложно.

Влияние на производительность

В примере выше мы видели, что платформа сгенерировала несколько запросов для получения элементов на каждом уровне иерархии. Но что, если иерархия будет содержать не 2, 3, 5 уровней, а 10, 20, 50! Чем больше уровней, тем больше запросов будет сформировано.

Плюс ко всему, в нашем примере запрос был очень простой. Но что, если это будет запрос тяжелого отчета, где условие "В ИЕРАРХИИ" будет применено множество раз. Если справочник очень большой, а пользователь в отчете случайно сделал отбор по пустой ссылке? Тогда будет выбран весь справочник!

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

Вот некоторые материалы, в которых Вы можете найти информацию о влиянии инструкции "В ИЕРАРХИИ" на производительность:

Сам по себе оператор "В ИЕРАРХИИ" очень мощный, но требует осторожного использования.

Делайте выводы!

Выводы делать Вам. Скажу лишь, что оператор "В ИЕРАРХИИ" используется платформой для системы компоновки данных, когда в условиях отбора присутствуют "В ГРУППЕ", "В ГРУППЕ ИЗ СПИСКА" и прочие. Думаю, не стоит объяснять, что при особых манипуляциях пользователи могу поставить очень сложный отбор в отчете или динамическом списке. Это может стать причиной значительного повышения нагрузки на всю информационную систему, "тормозам" или даже зависанию.

Ну и, разумеется, при разработке обращайте внимание на оператор "В ИЕРАРХИИ". Очень удобный с одной стороны, и опасный с другой.

Другие ссылки

80

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. insurgut 197 16.07.19 13:26 Сейчас в теме
А в чем мораль? В ИЕРАРХИИ работает ровно так, как задумано, и любые попытки оптимизации обычно только снижают производительность.

Ну а то, что может сделать пользователь прямого отношения к этому оператору не имеет никакого. Хуже или лучше сам оператор "В ИЕРАРХИИ" в зависимости от действий пользователя не становится.
3. YPermitin 3330 16.07.19 13:36 Сейчас в теме
(1) морали в моих статьях нет :)

Оператор все же может влиять на производительность. Посмотрите ссылки из статьи. Наверное, самый наглядный пример - это его появление в отчете на СКД. Пример на сайте gilev.ru.
6. kolya_tlt 11 16.07.19 13:47 Сейчас в теме
(3) мораль такова что данную конструкцию лучше запретить и выпилить из платформы. от неё одни не счастья.
8. insurgut 197 16.07.19 14:59 Сейчас в теме
(6) точно так же как и иерархию в справочниках/счетах учета. Дерево значений - тоже грохнуть. :)
12. for_sale 760 16.07.19 16:52 Сейчас в теме
(6)
Да-да, и ножи кухонные запретить - по новостям говорили, что одна женщина мужа таким ножом зарезала! И телеграм тоже запретить - там одни террористы! И вообще - давайте всё запретим!!! Тогда ничего не будет происходить и не будет никаких несчастий))
korppinen; +1 Ответить
9. insurgut 197 16.07.19 15:03 Сейчас в теме
(3) но это же очевидно, как и то, что альтернативы ей для иерархических справочников нет.
2. VmvLer 16.07.19 13:27 Сейчас в теме
4. YPermitin 3330 16.07.19 13:36 Сейчас в теме
5. ellavs 599 16.07.19 13:40 Сейчас в теме
Спасибо. Приятно смотреть, когда скриншоты с такими хорошими пояснениями.
taiwanchik; kuzyara; YPermitin; +3 Ответить
7. ids79 3182 16.07.19 14:35 Сейчас в теме
Спасибо.
Как всегда все понятно и доходчиво.
Я как раз в процессе написания статьи про иерархию в СКД.
YPermitin; +1 Ответить
17. YPermitin 3330 16.07.19 20:37 Сейчас в теме
(7) ждем с нетерпением!

Спасибо!
10. Dach 272 16.07.19 15:15 Сейчас в теме
Просто оставлю это здесь:

Теорию, которую нужно знать, чтобы понять логику работы любого дерева, хранящегося в плоской таблице:

https://infostart.ru/public/158512/

"В ИЕРАРХИИ" и "УПОРЯДОЧИТЬ ПО ИЕРАРХИЯ" / "ИТОГИ ПО ИЕРАРХИЯ"

https://infostart.ru/public/417128/
YPermitin; +1 Ответить
11. s22 19 16.07.19 15:56 Сейчас в теме
Лучше бы сделали в конфе теневую таблицу

Родитель | подчинены(любого уровня вложенности)

тогда все сведется к внутреннему соединению.
В запросах будет использоваться прозрачно.
FAMыч; SlavaKron; YPermitin; +3 Ответить
14. kote 499 16.07.19 17:38 Сейчас в теме
(11) не вариант, т.к. будет нужна будет еще одна промежуточная таблица подчиненности.. и сложности с выводом одного уровня подчиненности, не?
18. s22 19 16.07.19 20:39 Сейчас в теме
(14)
) не вариант, т.к. будет нужна будет еще одна промежуточная таблица подчиненности.. и сложности с выводом одного уровня подчиненности, не?

какие сложности?
"промежуточная таблица подчиненности"? зачем Есть справочник. Есть эта таблица.
22. kote 499 17.07.19 16:48 Сейчас в теме
(18) Как это реализуется в таблицах: одна запись (потомок) ссылается на одну запись (родитель)

Теперь, Вы пишите

Родитель | подчинены(любого уровня вложенности)


Т.е. тут либо родитель должен содержать все ссылки на потомков, либо потомки - на всех родителей

Теперь вопрос: как можно реализовать то, что Вы предлагаете без промежуточных таблиц?
Для каждого уровня вложенности создать еще одно поле? Тогда иерархические запросы будут совсем неудобны для использования..

Или есть еще какой-то способ?

Расскажите, если не сложно - как это должно выглядеть, пожалуйста.
23. s22 19 17.07.19 16:56 Сейчас в теме
(22)
Т.е. тут либо родитель должен содержать все ссылки на потомков, либо потомки - на всех родителей

2 поля.
Родитель и все его потомки
таблица теневая, т.е. делается на уровне платформы.

Запрос будет сводиться к внутреннему соединению.
13. Froloid 66 16.07.19 16:57 Сейчас в теме
Когда то крутилась в голове мысль "Как СУБД отрабатывает конструкцию "В иерархии"" (а ещё и конструкцию "Количество (Различные ..)". Но в условиях ненадобности интерес не довёл дело до трассировки запросов на стороне СУБД.

Однако гипотетически как получить иерархию было понятно и самым сложным нюансом казался "Как определить максимальную глубину справочника".

И вот в данном разборе я не вижу ответа на главный вопрос конструкции "В иерархии". В описании формулировка:
Поскольку на третьем уровне иерархии не присутствует ни одна группа справочника, то данный запрос более не выполняется


Чтобы выяснить это "Поскольку", на ум приходит только рекурсивные запросы начиная с корня для каждого последующего уровня, до тех пор, пока не получим пустой результат. То есть конструкция, которая не может быть отработана за одно обращение к СУБД (точнее одним запросом со стороны 1С).

Хорошо бы раскрыть этот ключевой нюанс данной конструкции.
RickyTickyTok; ogoneksergei; YPermitin; +3 Ответить
15. Dach 272 16.07.19 18:01 Сейчас в теме
(13)

Платформа при трансляции текста запроса задает глубину вложенности исходя из настроек справочника

на ум приходит только рекурсивные запросы начиная с корня


посмотрите (10), в первой публикации как раз этот вопрос наиболее полно и раскрыт
YPermitin; +1 Ответить
20. Froloid 66 17.07.19 11:25 Сейчас в теме
(15) То есть в указанном примере в конфигурации установлено ограничение по максимальной глубине в 3 уровня? С трудом верится.
21. Dach 272 17.07.19 12:47 Сейчас в теме
(20) а Вы и не верьте)) возьмите профайлер и потрассируйте запросы, меняя уровень иерархии
16. Dorosh 133 16.07.19 18:47 Сейчас в теме
Принято ругать конструкцию В ИЕРАРХИИ за тормознутость, но родной для скуля CTE работает еще медленнее. Как-то движимый любопытством написал и протестировал скульный запрос с CTE и 1с с иерархией. Оба запроса возвращали одинаковый набор данных из спр Контрагенты. Иерархия победила, за счет параллелизма. Рекурсивный запрос принципиально выполняется в 1 поток.
YPermitin; +1 Ответить
19. logarifm 1045 17.07.19 08:41 Сейчас в теме
Наглядные примеры того как не стоит обращаться из избыточными операторами. Но иногда без этого не обойтись. Ведь пользователю глубоко пофигу на производительность системы. Это наши проблемы. По этому еще интересней, когда В ИЕРАРХИИ и список групп они указывают.

Вообще автор молодец уже много статей написано по производительности и моменты работы Движка SQL. Ждем последующих статей...

ЗЫ. От себя еще хочу добавить СКД серьезно теряет производительность при группировке колонок (ведь за кулиссами там происходит нечто таинственное)
24. FreeArcher 83 18.07.19 06:53 Сейчас в теме
А если мы используем конструкцию В ИЕРАРХИИ (&П), но в параметр подставляется не группа, а элемент. Запросы будут усложнятся или платформа поймет, что эта запись равнозначна =&П?
25. SlavaKron 18.07.19 09:31 Сейчас в теме
(24) Есть ведь справочники с иерархией элементов, то есть родителем одного элемента является другой элемент.
26. FreeArcher 83 18.07.19 10:20 Сейчас в теме
(25) Есть. Но у меня вопрос когда элемент не имеет подчиненных.
Я хочу понять делая универсальным вызовы в запросе используя В или В ИЕРАРХИИ предполагая, что параметры могут принять массив значений или группу утяжеляем ли мы план запросов или 1С "умная" и она поймет данную ситуацию?
27. Evil Beaver 6199 18.07.19 11:24 Сейчас в теме
(44) Смотришь на автора, сначала плюсуешь, потом читаешь.
Оставьте свое сообщение