Имя: Пароль:
1C
 
Оптимизация запрос
, ,
0 BubbleGumm
 
21.03.19
15:50
Есть простой запрос:
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    ЛОЖЬ И Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаНоменклатуры)

Он естественно вернется пустым. Если убрать второе условие - "Номенклатура.Ссылка В ИЕРАРХИИ(&ГруппаНоменклатуры)" он отработает моментально, а если не убирать есть задержка (скорость не замерял, чисто визуальное наблюдение в консоли заросов). Как SQL разбирает условия? Как сделать оптимальнее?
1 Fragster
 
гуру
21.03.19
15:55
использовать построитель запроса или "заглушки" в тексте запроса и СтрЗаменить, если использование построителя невозможно. есть еще объект встроенного языка "СхемаЗапроса", но он неудобный.
2 mikecool
 
21.03.19
15:57
условия И отрабатывают все
В всегда тормоз
3 BubbleGumm
 
21.03.19
15:58
(2) Это точно? Где можно почитать?
4 Вафель
 
21.03.19
15:58
для условия в ИЕРАРХИИ сервер 1с делает временную таблицу.
вот на нее время и уходит
5 Вафель
 
21.03.19
15:59
сам скл сервер конечно же умеет короткие логические выражения вычислять
6 Fragster
 
гуру
21.03.19
15:59
(2) нет
7 Fragster
 
гуру
21.03.19
15:59
(4) да
8 Йохохо
 
21.03.19
16:00
кажется вопрос делает ли скуль ленивые вычисления при оптимизации
9 mikecool
 
21.03.19
16:00
(6) до первого Ложь, а потом прерывает?
11 BubbleGumm
 
21.03.19
16:01
Что иерархия это тормоз, понятно, выше комментарий интересный, что условия И отрабатываются все, не знал этого, где прочесть?
12 Fragster
 
гуру
21.03.19
16:02
(9) нет, у него анализатор есть, если условие всегда ложно, то он ничего не будет делать. в файловой анализатор тупой, хз, как он работает. в случае (0) проблема в (4)
13 mikecool
 
21.03.19
16:06
(11) это я из логики ошибся, ИЛИ проверяются все
14 ViSo76
 
21.03.19
16:13
(0) Понятия ИЕРАРХИИ в SQL не существует, по этому это решается другими способами типа IN ( скорее всего из ранее подготовленный временной таблицы. По этому есть задержка
15 BubbleGumm
 
21.03.19
16:14
(14) Да, это видимо сервер 1С готовит ее не зависимо от прочих условий
16 aleks_default
 
21.03.19
16:16
(13)нет
17 Йохохо
 
21.03.19
16:29
(15) он ее не готовит, он переводит текст с одного языка запросов в другой
18 BubbleGumm
 
21.03.19
16:33
(17) Ну да
19 Йохохо
 
21.03.19
16:35
(18) а дальше ответ в (12)
20 rphosts
 
21.03.19
16:35
База не файловая?
21 Eiffil123
 
21.03.19
16:40
Думаю, В ИЕРАРХИИ в 1С написан более оптимально, чем можно самостоятельно его же сделать кодом или запросами.

Хотя, как вариант, можно сделать регистр сведений с измерениями 1.РодительГруппа 2.Ссылка и каким-то образом записывать данные в него (например, ПриЗаписи элемента справочника).   Но это уже какие-то извращения. Но я бы так не делал.
22 rphosts
 
21.03.19
16:46
(21) зачем думать если можно знать? 1с сделала неплохо в целом, но часто опираясь на знания особенностей для конкретной реализации можно сделать значительно лучше
23 Fragster
 
гуру
21.03.19
17:38
>Думаю, В ИЕРАРХИИ в 1С написан более оптимально, чем можно самостоятельно его же сделать кодом или запросами.

нет, можно перейти на nested sets. ну, или на materialized path. и тогда аналог "в иерархии" будет работать ощутимо быстрее и его можно будет использовать в качестве условий соединения.
проблема в некотором замедлении записи при изменении иерархии, что, в принципе, терпимо. но если б была нативная поддержка платформой, то вместо своих РС и кучи записи в цикле могло бы быть всего по паре запросов типа update.
24 Eiffil123
 
21.03.19
18:03
(22) и как?
25 Eiffil123
 
21.03.19
18:05
(23) А как быть с распределенными базами данных, когда сначала приезжает подчиненный элемент с указанием битой ссылки на родителя, а родитель после этого только грузится?
26 Fragster
 
гуру
21.03.19
18:14
(25) и что?
27 rphosts
 
21.03.19
18:18
(24) повторяю "опираясь на знания особенностей для конкретной реализации"
28 Eiffil123
 
21.03.19
18:22
(26) "nested sets" или "materialized path" - это какие-то отдельные таблицы/поля? или они как-то динамически вычисляются? Если поля, тогда при записи элемента справочника может быть неизвестен его родитель (при загрузке по РБД).
29 rphosts
 
21.03.19
18:26
(28) вы про план выполнения запроса покурите для начала.
30 Fragster
 
гуру
21.03.19
18:37
(28) ты же прочитал, что такое nested sets и materialized path? проблемы с РИБ могут быть только в случае nested sets, да и то они решаемы.
31 Конструктор1С
 
22.03.19
06:24
(1) СхемаЗапроса отличный инструмент, но нужно уметь его готовить
32 Evg-lylyk
 
22.03.19
07:36
33 Провинциальный 1сник
 
22.03.19
07:40
(0) Думаю, это недокументированная особенность реализации sql-сервера. В стандарте sql скорее всего не регламентирован порядок вычисления логических выражений и поведение при "очевидном результате".
34 OpKc
 
22.03.19
08:54
если вычисление первого условия занимает очень мало времени, то можно сделать что-то вроде такого:
[code]
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    &Параметр1
    И ВЫБОР
            КОГДА &Параметр1
                ТОГДА Номенклатура.Ссылка В ИЕРАРХИИ (&ГруппаНоменклатуры)
            ИНАЧЕ ИСТИНА
        КОНЕЦ
[code]
35 OpKc
 
22.03.19
09:05
а лучше так

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    ВЫБОР
            КОГДА &Параметр1
                ТОГДА Номенклатура.Ссылка В ИЕРАРХИИ (&ГруппаНоменклатуры)
            ИНАЧЕ ЛОЖЬ
        КОНЕЦ
36 rphosts
 
22.03.19
09:15
(33) у мс-скл порядка 80 правил ускоряющих выполнение запроса... Скорее поверю что ТС ошибся
37 1С Ассенизатор ПРОФ
 
22.03.19
11:39
(0) В ИЕРАРХИИ убрать нужно
38 xXeNoNx
 
22.03.19
11:48
(35) Фу...
39 OpKc
 
22.03.19
11:56
(38) какие Ваши предложения?
40 xXeNoNx
 
22.03.19
12:02
(39) пока наблюдать
41 xXeNoNx
 
22.03.19
12:03
(39) Плохо когда у тебя в секции ГДЕ есть еще и ВЫБОР КОГДА...
42 OpKc
 
22.03.19
12:54
(41) чем именно это плохо? Интересуюсь не из праздного любопытства, а чтобы знания подтянуть.

Вообще, эта конструкция позволяет избежать проверки обоих условий в случае, если первое не выполняется. А ситуация из (0) действительно имеет место быть, я запрос ТСа в консоли с замером прогонял, - 0,8с выполняется. Мой в случае &Параметр1=Ложь выполняется мгновенно.
43 BubbleGumm
 
22.03.19
14:17
(35) Да, этот мгновенно отрабатывает. Присоединяюсь к вопросу к (41), чем это плохо?
44 Eiffil123
 
27.03.19
10:49
(43) А если передавать В ИЕРАРХИИ пустую ссылку, разве будет долго отрабатывать?
45 OpKc
 
27.03.19
13:50
(44) ещё раз замерил запрос из (0):

- при передаче группы номенклатуры отработал в среднем за 0,4 сек
- при передаче пустой ссылки отработал в среднем за 1,2 сек
46 xXeNoNx
 
27.03.19
14:04
(42) (43) Если я не ошибаюсь, то в случае ВЫБОР КОГДА в секции ГДЕ, оптимизатор может ошибаться с выбором плана запросов...
Поправьте меня, если не прав
47 Sapiens_bru
 
27.03.19
19:17
(46) Не прав. В секции ГДЕ определяется вариант поиска данных в индексах или куче. Вариант с ВЫБОР КОГДА не использует индекс ни при каких условиях. Ну а плохо это или не очень зависит от запроса, селективности условия и наличия индекса в принципе.
Обычно такое условие потенциальная ошибка. Но не по причине ошибки оптимизатора, просто он так работает.
48 H A D G E H O G s
 
27.03.19
19:33
(47) 1С достаточно умен, чтобы ВЫБОР в ГДЕ транслировать в нормальный SQL запрос, если там условие не завязано на значение поля таблицы.
49 H A D G E H O G s
 
27.03.19
19:33
Так нельзя:

ГДЕ
    ВЫБОР
            КОГДА Номенклатура.Код=&Код
                ТОГДА Номенклатура.Код = &Код
            ИНАЧЕ ИСТИНА
        КОНЕЦ

а так можно:

ГДЕ
    ВЫБОР
            КОГДА &ОтбиратьПоКоду
                ТОГДА Номенклатура.Код = &Код
            ИНАЧЕ ИСТИНА
        КОНЕЦ
50 Sapiens_bru
 
27.03.19
20:02
(49) Ваша правда. Проверил профайлером.
В любом случае стоит себя отучать от вычислений над индексированными полями
51 H A D G E H O G s
 
27.03.19
20:16
(50) Надо отучать мыслить догмами. Индексировать ВТ, всегда помещать отбор в параметры вирттаб, не использовать в ГДЕ ВЫБОР. Вот это всё.
52 OpKc
 
28.03.19
06:53
(48),(49) Спасибо за объяснение