Имя: Пароль:
1C
1С v8
В ИЕРАРХИИ
,
0 Darklight
 
25.07.13
10:50
Слышал ранее, что в 1С8 конструкция запросов "В ИЕРАРХИИ" работает очень  не оптимально. Из анализа SQL трассировок - видел, что такие конструкции порождают создание временные таблицы (причём целый набор) и уже их объединённый результата далее подставляется в SQL оператор "IN".
Соответственно, если в запросе будет несколько таких условий, то он будет   существенно замедлен.
А если будет несколько условий над одним и теми же полями - то они никак не будут оптимизированы - для каждого будут созданы отдельные наборы временных таблиц и отдельные выборки.
Причём в запросах по бухгалтерским регистрам такие конструкции бывают очень частыми и в очень большом количестве для отбора по иерархии счетов.

Вот и мой вопрос - действительно ли всё так плохо и не эффективно? И стоит ли проводить существенную оптимизацию запросов, в которых содержится целый ворох условий вида "В ИЕРАРХИИ" или сейчас платформа 1С 8 (пока понимаем последний релиз редакции 8.2) более менее эффективно справляется с такими конструкциями и нет особого смысла тут что-то накручивать? Особенно если речь идёт об запросах, используемых в отчетах?
1 skunk
 
25.07.13
10:51
1с их сама тихой сапой оптимизирует ... так чтоне замарачивайся ... ну или используй пакеты
2 ДенисЧ
 
25.07.13
10:52
Работает - не трогай
3 Ёпрст
 
25.07.13
10:54
дасистак
4 Галахад
 
гуру
25.07.13
10:54
Очевидно же. Не устраивает скорость - надо что-то делать. Устраивает, не надо.
5 Darklight
 
25.07.13
10:55
(1)В чём заключается оптимизация?
(2)Работает... но не шибко быстро
6 ИС-2
 
naïve
25.07.13
10:55
(0) да. В иерархии работает медленно. Делал проверку в записи контрагента - запрос по 1 элементу выполнялся 1 сек и больше.

Сейчас запрос по конт. инф. с иерархией работает медленно
7 Darklight
 
25.07.13
10:57
(4)Ну, скорость никогда не устраивает, и никогда не будет устраивать. А анализировать - насколько велик вклад таких конструкций в общее замедление - не просто.
Просто хотелось бы что-то сделать на глобальном уровне архитектуры плана счетов и отказаться от использования таких конструкций (в большинстве своём) без существеннгых переделок имеющихся запросов.
8 Darklight
 
25.07.13
10:58
(6)Проблема резко усугубляется когда в запросе становится  много таких условий.
9 skunk
 
25.07.13
10:59
из последнего

При исполнении запроса, для всех условий В ИЕРАРХИИ с одинаковым значением параметра, формируется одна временная таблица на один пакетный запрос.

Оптимизирована работа запроса, при использовании конструкции В ИЕРАРХИИ. Оптимизирована работа системы компоновки данных с источником данных в виде запроса, при использовании конструкций В ГРУППЕ и В ГРУППЕ ИЗ СПИСКА.
10 Darklight
 
25.07.13
11:05
Вот, например, простой запрос с большим количеством конструкций "В ИЕРАРХИИ".
Можно сказать, ЧТО ЭТО ЧАСТЬ большого запроса, где подобных вставок очень многого (и не обязательно в конструкции "ВЫБОР").
И пакетные запросы тут не особо спасают (ну только если их специально переписывать, чтобы минимизировать такие выборки "В ИЕРАРХИИ")

ВЫБРАТЬ
    ВЫРАЗИТЬ(ВзаиморасчетыСКонтрагентамиОстатки.Субконто1 КАК Справочник.Контрагенты) КАК Контрагент,
    ЕСТЬNULL(ВЫРАЗИТЬ(ВзаиморасчетыСКонтрагентамиОстатки.Субконто2 КАК Справочник.ДоговорыКонтрагентов), "без договора") КАК ДоговорКонтрагента,
    Счет,
    ВЫБОР
    КОГДА Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПоставщикамиИПодрядчиками))
    ТОГДА ВзаиморасчетыСКонтрагентамиОстатки.СуммаОстаток
    ИНАЧЕ 0
    КОНЕЦ КАК СуммаРасчетыСПоставщикамиИПодрядчиками,
    ВЫБОР
    КОГДА Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПокупателямиИЗаказчиками))
    ТОГДА ВзаиморасчетыСКонтрагентамиОстатки.СуммаОстаток
    ИНАЧЕ 0
    КОНЕЦ КАК СуммаРасчетыСПокупателямиИЗаказчиками,
    ВЫБОР
    КОГДА Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСРазнымиДебиторамиИКредиторами))
    ТОГДА ВзаиморасчетыСКонтрагентамиОстатки.СуммаОстаток
    ИНАЧЕ 0
    КОНЕЦ КАК СуммаРасчетыСРазнымиДебиторамиИКредиторами,
    ВЫБОР
    КОГДА Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда))
    ТОГДА ВзаиморасчетыСКонтрагентамиОстатки.СуммаОстаток
    ИНАЧЕ 0
    КОНЕЦ КАК СуммаРасчетыСПерсоналомПоОплатеТруда,
    ВЫБОР
    КОГДА Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПодотчетнымиЛицами_))
    ТОГДА ВзаиморасчетыСКонтрагентамиОстатки.СуммаОстаток
    ИНАЧЕ 0
    КОНЕЦ КАК СуммаРасчетыСПодотчетнымиЛицами
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Остатки(
            &ДК,
            (Счет В ИЕРАРХИИ(ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПоставщикамиИПодрядчиками),
                             ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПокупателямиИЗаказчиками),
                             ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСРазнымиДебиторамиИКредиторами),
                             ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда),
                             ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПодотчетнымиЛицами_),
                             ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.РасчетыСПерсоналомПоПрочимОперациям))
            И Счет НЕ В ИЕРАРХИИ(&Исключение))
            ,
            ) КАК ВзаиморасчетыСКонтрагентамиОстатки
11 skunk
 
25.07.13
11:09
(10)пакетный улутшит производительность данного на порядок ...
12 Darklight
 
25.07.13
11:11
(9)Насколько эффективно будет сделана такая замена, если запрос ссоставной и такие конструкции будут разбросаны по разным под запросам, в т.ч. частям пакета?
(10)Вот я и говорю, конечно даннйы запрос можно существенно улучить - существенно его переписав. Был вопрос - стоит ли вообще городить эту оптимизацию? Причём мне не очень хотется переписывать соьтни запросов на совершенно новую архитектуру. Мне хочется - модернизировать несильно план счетов ;)
13 skunk
 
25.07.13
11:17
(12)ну если раньше скул при выполнении твоего запроса городил, в темпдиби, что-то около 6 таблиц и потом их селектил ... то сейчас таблица будет одна ... думаю должно повысить существенно
14 Darklight
 
25.07.13
11:20
(13)То есть, гордиться ручную оптимизацию смысла большого нет?
15 skunk
 
25.07.13
11:22
(14)поставь последнию версию и сравни ... только незабудь отказаться от поддержки предыдущих версий
16 palpetrovich
 
25.07.13
11:35
а можно примерчик, как оптимизировать такое:
ВЫбрать Ссылка из Справочник.Номенклатура ГДЕ Ссылка в ИЕРАРХИИ(&ВыбГруппа)
17 palpetrovich
 
25.07.13
11:43
+(16) что и требовалось доказать, одни блаблабла :)
18 skunk
 
25.07.13
11:44
(17)ты чего так долго ждал ... целых 8 минут
19 Darklight
 
25.07.13
11:46
(17)Речь не идёт об оптимизации всего и вся, особенно простых или слишком универсальных конструкций.
Приведённый в (16) запрос нельзя оптимизировать, если конечно нет каких-либо особых и не сказанных ограничивающих "условий" или эта оптимизация не превращается в экстремальную, с хешированием и т.п. хренью
20 palpetrovich
 
25.07.13
11:55
(18) ну как, дал время на подготовку канешн...
(19) почему нельзя? а это:

ВЫбрать Ссылка из Справочник.Номенклатура
ГДЕ Ссылка = Номенклатура1
ИЛИ Ссылка = Номенклатура2
ИЛИ Ссылка = Номенклатура3
...
21 ДенисЧ
 
25.07.13
11:59
(20) ИЛИ 1с не советует использовать в условиях...
22 Darklight
 
25.07.13
11:59
(20)Вот это и есть те самые особые "условия"
Вам же как-то нужно определить эти самые "Номенклатура1..3" (это параметры? Вы не указали символ "&"). Это конечный набор? Каков его размер? Вы будет проводить оптимизацию разных размеров этого набора? Тут много - очень много особых условий возникает. Он не были Вами озвучены в задаче оптимизации!
23 Darklight
 
25.07.13
12:00
(21) Но почему? вРОДЕ sql НЕПЛОХО ИХ ОТРАБАТЫВАЕТ, когда их количество не превышает все разумные пределы ;)
24 Darklight
 
25.07.13
12:02
ИМХО, 1-вый вариант лучше, чем второй

1.
ВЫБРАТЬ
Ссылка
ИЗ Справочник.Номенклатура
ГДЕ Ссылка = Номенклатура1
ИЛИ Ссылка = Номенклатура2
ИЛИ Ссылка = Номенклатура3

2.
ВЫБРАТЬ
Ссылка
ИЗ Справочник.Номенклатура
ГДЕ Ссылка В(Номенклатура1,
             Номенклатура2,
             Номенклатура3)
25 ДенисЧ
 
25.07.13
12:02
(23) Патамучта 1с не рекомендует :-)
Типа индексы не будут использоваться.

1. Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероятность возникновения блокировок. Вместо этого следует разбить один запрос на несколько и объединить результаты.


2. Не рекомендуется использовать логическое ИЛИ в условиях соединения, то есть в секции ПО запроса. Это так же может привести к выбору неоптимального плана и медленной работе запроса. Простого универсального способа переписать такой запрос без использования ИЛИ не существует. Следует проанализировать решаемую задачу и попытаться найти другой алгоритм ее решения.

3. Если в конфигурации описано несколько ролей с разным ограничением доступа на уровне записей (RLS), то не следует назначать одному пользователю более одной такой роли. Если один пользователь будет включен, например, в две роли с RLS - бухгалтер и кадровик, то при выполнении всех его запросов к их условиям будут добавляться условия обоих RLS с использованием логического ИЛИ. Таким образом, даже если в исходном запросе нет условия ИЛИ, оно появится там после добавления условий RLS. Такой запрос так же может выполняться неоптимально - медленно и с избыточными блокировками.  

Вместо этого следует:


Пересмотреть состав ролей таким образом, чтобы к одному объекту метаданных давала доступ только одна роль (на чтение, запись и т.п.);
При необходимости разработки нескольких ролей, предоставляющих доступ к одному объекту метаданных, задавать в них одинаковые условия RLS. В этом случае к тексту запроса будет добавлено только одно условие, без объединения по ИЛИ;
Либо если это допустимо с точки зрения прикладной области, создать "смешанную" роль - "бухгалтер-кадровик" и прописать ее RLS таким образом, чтобы избежать использования ИЛИ в условии, а пользователя включить в эту одну роль.
26 palpetrovich
 
25.07.13
12:03
(22) ну не указал "&" - мне и в пофигураторе хватает этого ...вечно приходится переключаться блин

зы: кста, кто как оптимизирует надбор этого "&"
pps: пунтосвитчер на сервер - не предлагать :)
27 Darklight
 
25.07.13
12:08
(25) Надо будет потестить ;)
(26)ALT+3 8 на цифровой клаве - в любой раскладке и состоянии NumLock (правда последний лучше включать - не все приложения на все клавиши будут адекватно реагировать)
А так же полезны ALT+6 0 и ALT+6 2 для < > соответсвенно
28 palpetrovich
 
25.07.13
12:10
(27) спасибо,  надо запомнить
29 ptiz
 
25.07.13
12:14
раскладка клавиатуры от Чистова рулит
30 Darklight
 
25.07.13
12:17
(28)Ну запомни ещё ALT+1 6 ALT+1 7 ALT+2 2 ALT+2 6 и т.д.
ну и ALT+1 ALT+2 ALT+3 ...
31 palpetrovich
 
25.07.13
12:27
(30) а где в коде используется ALT+16 к примеру?
32 Darklight
 
25.07.13
12:36
(31)А почему сразу в коде? Хот, например, в комментарии к коду можно ;) Или в описании инструкций - я люблю этот символ для разграничении пунктов меню ;)
33 palpetrovich
 
25.07.13
12:38
(32) не надо мне там, ограничемся благодарностями за (27) ;)
34 Darklight
 
25.07.13
12:38
А ALT+2 0 - показывает путь к доступу к секретным функциям 1С (Привет "СЕТЬ").
35 Darklight
 
25.07.13
12:39
(33)Какой же Вы скупой на благодарности - лишнюю благодарность  прибережёте ;)
36 Darklight
 
25.07.13
12:46
(25)В соответствие с данной рекомендацией получается, что (20) имеет смысл переписать вот так
3.
ВЫБРАТЬ
Ссылка
ИЗ Справочник.Номенклатура
ГДЕ Ссылка = Номенклатура1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
Ссылка
ИЗ Справочник.Номенклатура
ГДЕ Ссылка = Номенклатура2

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
Ссылка
ИЗ Справочник.Номенклатура
ГДЕ Ссылка = Номенклатура3




И, соответственно, это 3-тий вариант будет более оптимален по производительности?
37 Darklight
 
26.07.13
10:40
ну так что будет быстрее и эффективнее?
38 ДенисЧ
 
26.07.13
10:41
(37) А проверить?
39 Darklight
 
26.07.13
10:51
(38)Конечно - это всегда можно - но качественный эксперимент требует больших усилий. Пока пытаюсь ограничиться мнениями компетентных людей, желательно уже прошедших через это!
Основная теорема систематики: Новые системы плодят новые проблемы.