Имя: Пароль:
1C
 
Как оптимизировать запрос с "НЕ В ()"?
,
0 mikecool
 
24.01.19
14:16
Есть рекомендация, что условие
Где Поле В (выборка)
оптимальнее заменить на
выборка во врем таблицу
+
внутреннее соединение с этой временной таблицей
а как быть с
НЕ В (выборка)
?
1 mikecool
 
24.01.19
14:17
полное соединение по НЕ поле = поле временной таблицы?
2 ДенисЧ
 
24.01.19
14:17
ТОчно так же, только условие другое
3 Курцвейл
 
24.01.19
14:18
(1) написать НЕ в условии соединения
4 mikecool
 
24.01.19
14:18
(2) будь лаской, расскажи
5 mikecool
 
24.01.19
14:18
(3) и тоже внутреннее соединение
6 mikecool
 
24.01.19
14:18
?
7 Курцвейл
 
24.01.19
14:18
(1) почему полное? так же внутреннее
8 mikecool
 
24.01.19
14:19
ага, спасибо, думал об этом, но картина в голове не сложилась )
9 Курцвейл
 
24.01.19
14:21
Оптимизация для файловой версии?
10 mikecool
 
24.01.19
14:24
(9) не, это же рекомендации от 1с!
11 Кир Пластелинин
 
24.01.19
14:28
есть null?
12 Buster007
 
24.01.19
14:30
а я бы порекомендовал
левое + есть нулл
13 mikecool
 
24.01.19
14:30
(12) тоже верно
а как быть в условиях виртуальных таблиц?
там остается только В() и НЕ В()?
14 Вафель
 
24.01.19
14:32
прежде чем следовать рекомендациям хорошо бы план запроса посмотреть.
временные делать на каждый чих не всегда хорошо, ведь на создание таблицы тоже тратится время
15 mikecool
 
24.01.19
14:34
(14) как пишут в рекомендациях - это время ничтожно мало, а выигрыш может быть существенным
16 Вафель
 
24.01.19
14:34
(15) а может и не быть, а наоборот
17 Вафель
 
24.01.19
14:34
(15) далек ты еще от оптимизации
18 Buster007
 
24.01.19
14:35
(13) делаешь свою таблицу по условия левое + есть нулл, а потом ее используешь в фильтрах вирт. таблицы.
Также, в рекомендациях, присутствует то, что таблицу, которую будешь использовать в фильтрах, следует проиндексировать по полям условий
19 mikecool
 
24.01.19
14:37
и вот еще конструкция смущает, типа
Справочник.Номенклатура
левое соединение
ОстаткиТОваров.Остатки
По

в данном случае список номенклатуры определен(есть в вирт. таблице)
стоит ли писать
Справочник.Номенклатура
левое соединение
ОстаткиТОваров.Остатки(, Номенклатура В())
По
или для левого соединения быстрее будет не рассчитывать таблицу остатков?
20 Buster007
 
24.01.19
14:37
(17) вопрос оптимизации приходит тогда, когда что-то плохо работает. Плохо будет работать или нет до реальной работы пальцем в небо практически, если не писать полную чешуйню, конечно
21 mikecool
 
24.01.19
14:37
(17) а я и не спорю ))
(18) эт я в курсе
22 mikecool
 
24.01.19
14:37
(20) лучше сразу написать ровно, чем потом ковыряться в криво )
23 ДенисЧ
 
24.01.19
14:38
(19) Зависит от соотношения списка номенклатуры ко всему количеству.
24 Buster007
 
24.01.19
14:40
(19) какой-то у тебя странный вопрос
если тебе не нужна номенклатура по которой нет остатков, то и соединение нафиг не нужно
25 mikecool
 
24.01.19
14:40
(23) я чего думаю - левое соединение и так шустрое и при взятии актуального среза стоит ли дополнительно проводить расчет ВТ или таки зависит от кол-ва номенклатур?
26 Buster007
 
24.01.19
14:45
(25) представим, что ОстаткиТОваров.Остатки(, Номенклатура В()) возвращает тебе остатки по 90% номенклатуры, какой смысл накладывать дополнительный фильтр?

Кстати, здесь надо понимать еще то, что реально у тебя может получиться соединение со вложенным запросом при таком подходе
левое соединение
ОстаткиТОваров.Остатки(, Номенклатура В())
27 Buster007
 
24.01.19
14:46
+(26) хотя без отбора не будет
28 mikecool
 
24.01.19
14:46
(26) это понятно
вот процент номенклатуры - хз, какой может быть
29 Кир Пластелинин
 
24.01.19
14:46
(18) слепо следовать рекомендациям касательно индексации полей условий вт не стоит, т.к. это может как и в плюс, так и в минус в итоге сыграть. в каждом случае смотреть индивидуально профит от индексации.
30 vvp91
 
24.01.19
14:47
Номенклатура, которой нет в реализациях:

ВЫБРАТЬ
    ДД.Номенклатура
ИЗ
    Справочник.Номенклатура КАК ДД
ГДЕ
    НЕ ИСТИНА В (
        ВЫБРАТЬ
            ИСТИНА
        ИЗ
            Документ.РеализацияТоваровУслуг.Товары КАК ТТ
        ГДЕ
            ТТ.Номенклатура = ДД.Ссылка
    )
31 vvp91
 
24.01.19
14:48
Вместо ДД.Номенклатура надо ДД.Ссылка
32 Buster007
 
24.01.19
14:48
(29) подскажи, как это сделать, не имея реального объема данных на которых "можно пощелкать"?
33 Buster007
 
24.01.19
14:50
(30) ПЕРВЫЕ 1 можно добавить
34 vvp91
 
24.01.19
14:52
(33)
В основной ВЫБРАТЬ не нужно.
Запрос возвращает всю номенклатуру, которой нет в реализациях.
В коррелированный подзапрос можно и добавить, но тоже не нужно - оптимизатор умнее все равно.
35 Кир Пластелинин
 
24.01.19
14:55
(32) что именно? понять есть ли профит от индекса или нет? значит заиметь этот реальный объем данных для понимания эффективности. какие тут варианты то.
36 ДенисЧ
 
24.01.19
14:55
(25) Если у тебя в списке 5 товаров, а на остатках 50 000, то имеет смысл накладывать условие в таблице остатков.
Если же в списке у теба 45 000, то смысла особого нет
37 Вафель
 
24.01.19
14:56
вт стоит индексировать когда она используется более 1 раза. иначе никакаого преимущества перед хэшджойном не будет
38 DexterMorgan
 
24.01.19
14:57
(30) Соединить и отобрать по NULL не быстрее будет разве?
39 DexterMorgan
 
24.01.19
14:58
(30) да точно (38) быстрее будет
40 DexterMorgan
 
24.01.19
15:02
(0) Сколько тебе лет? Просто хочу понять, проблемы с памятью или это у тебя любимая тема?

Покритикуйте решение... нужно подбирать ссылки на документ 1 в табчасть документа 2
41 mikecool
 
24.01.19
15:55
(40) как хорошо, когда есть внешняя память )
42 vvp91
 
24.01.19
16:22
(38), (39) Да, конечно, соединение будет быстрее

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


СУБД Postgres 10, платформа 8.3.10.2699, конфигурация 1С:ЕРП 2.2
Статистика:
Справочник.Номенклатура - 17605
Документ.РеализацияТоваровУслуг - 286
Документ.РеализацияТоваровУслуг.Товары - 1441

В результате запроса "Номенклатура, которой нет в реализациях" должно быть 16639 записей

1. Коррелированный подзапрос из (30) - среднее время 6.9 сек.

2. Соединение с отбором по NULL из (38) - среднее время 0.9 сек.

ВЫБРАТЬ
    ДД.Ссылка
ИЗ
    Справочник.Номенклатура КАК ДД
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК ТТ
        ПО ТТ.Номенклатура = ДД.Ссылка
ГДЕ
    ТТ.Номенклатура ЕСТЬ NULL


3. Выборка с подзапросом к временной таблицей - среднее время 1.0 сек.

ВЫБРАТЬ РАЗЛИЧНЫЕ
    ТТ.Номенклатура
ПОМЕСТИТЬ
    Использовано
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТТ
;

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


4. Коррелированная выборка с временной таблице - среднее время 2.9 сек.

ВЫБРАТЬ РАЗЛИЧНЫЕ
    ТТ.Номенклатура
ПОМЕСТИТЬ
    Использовано
ИЗ
    Документ.РеализацияТоваровУслуг.Товары КАК ТТ
;

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


5. Выборка с подзапросом к физической таблице - среднее время 1.0 сек.

ВЫБРАТЬ
    ДД.Ссылка
ИЗ
    Справочник.Номенклатура КАК ДД
ГДЕ
    НЕ ДД.Ссылка В (
        ВЫБРАТЬ
            ТТ.Номенклатура
        ИЗ
            Документ.РеализацияТоваровУслуг.Товары КАК ТТ
    )
43 DexterMorgan
 
25.01.19
13:22
(41) Обращайся
44 AndyD
 
25.01.19
18:44
(37) бред. зависит от количества соединяемых строк.

был у меня один здоровый запрос, где индексация помогла ускорить все на порядок.
45 xXeNoNx
 
26.01.19
09:03
(0) а можно ссылку на рекомендацию?
46 RomanYS
 
26.01.19
12:27
(42) а где комбинация 2 и 3: подзапрос и соединение?
Независимо от того, куда вы едете — это в гору и против ветра!