Вход | Регистрация
 

Как оптимизировать запрос с "НЕ В ()"?

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

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

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

   vvp91
 
31 - 24.01.19 - 14:48
Вместо ДД.Номенклатура надо ДД.Ссылка
   Buster007
 
32 - 24.01.19 - 14:48
(29) подскажи, как это сделать, не имея реального объема данных на которых "можно пощелкать"?
   Buster007
 
33 - 24.01.19 - 14:50
(30) ПЕРВЫЕ 1 можно добавить
 
 
   vvp91
 
34 - 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 раза. иначе никакаого преимущества перед хэшджойном не будет
   DexterMorgan
 
38 - 24.01.19 - 14:57
(30) Соединить и отобрать по NULL не быстрее будет разве?
   DexterMorgan
 
39 - 24.01.19 - 14:58
(30) да точно (38) быстрее будет
   DexterMorgan
 
40 - 24.01.19 - 15:02
(0) Сколько тебе лет? Просто хочу понять, проблемы с памятью или это у тебя любимая тема?

Покритикуйте решение... нужно подбирать ссылки на документ 1 в табчасть документа 2
   mikecool
 
41 - 24.01.19 - 15:55
(40) как хорошо, когда есть внешняя память )
   vvp91
 
42 - 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 сек.
ВЫБРАТЬ
    ДД.Ссылка
ИЗ
    Справочник.Номенклатура КАК ДД
ГДЕ
    НЕ ДД.Ссылка В (
        ВЫБРАТЬ
            ТТ.Номенклатура
        ИЗ
            Документ.РеализацияТоваровУслуг.Товары КАК ТТ
    )

   DexterMorgan
 
43 - 25.01.19 - 13:22
(41) Обращайся
   AndyD
 
44 - 25.01.19 - 18:44
(37) бред. зависит от количества соединяемых строк.

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


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.
Рекламное место пустует