Имя: Пароль:
1C
1С v8
Какой запрос лучше
0 raytan
 
15.03.17
09:54
УПП 8.2
Стоит задача найти все серии номенклатуры, по которым не было движений.
Вижу два решения:
1.
К СериямНоменклатуры левым соединением ПартииТоваровНаСкладах и условие на NULL для Партии.
2.
Выбрать СерииНоменклатуры и в условие СерииНоменклатуры Не В (Запрос Различные Из ПартииТоваровНаСкладах)

И первое, и второе решения какие то не очень... Может быть есть более правильный подход для решения подобной задачи ?
Если нет, то как Вы считаете какой запрос более оптимальный ?
1 Живой Ископаемый
 
15.03.17
10:00
1. решение правильное.
Так делается во всех диалектах СКЛ, где не реализовано исключающее соединение специальным оператором.

за второе решение на собеседованиях обычно заканчивают разговор.
2 raytan
 
15.03.17
10:03
(1) Хорошо, спасибо :)
3 Ildarovich
 
15.03.17
12:12
(1) Сомнительные утверждения.

Нужно знать тип СУБД, размеры таблиц и прочее.
Запросы элементарные, легче и точнее всего не рассуждать теоретически, а сравнить время на реальных данных.

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

Если считать второй вариант по какой-то причине (по какой?) ненадежным, то можно ОБЪЕДИНИТЬ таблицу всех серий с таблицей РАЗЛИЧНЫХ серий из партий и сгруппировав по серии выбрать "имеющие количество(*) = 1".
4 H A D G E H O G s
 
15.03.17
12:22
Индексы, хериндексы.

Будет scan 2-х таблиц при merge join
Наличие индекса по Серии в регистре лишь позволит отказаться от предварительной сортировки регистра.
5 RomanYS
 
15.03.17
12:26
(4) Расшифруй, пожалуйста.
(1) прав?
По "человечьи" мне (3) ближе.
6 H A D G E H O G s
 
15.03.17
12:44
(1) Прав.
7 H A D G E H O G s
 
15.03.17
12:46
Смотрите на проблему проще.
Вам нужно сравнить 2 гигантские таблицы (мы же о серьезных вещах толкуем).

Оптимальнее, чем merge join - это не сделать, тем более, что одна из таблиц уже отсортирована.
8 Живой Ископаемый
 
15.03.17
12:56
" строк в результате соединения перед проверкой на NULL. " - Никакого ПЕРЕД не будет
поэтому 1 и правильно
9 Живой Ископаемый
 
15.03.17
12:58
10 Живой Ископаемый
 
15.03.17
13:00
NOT EXIST и EXCEPT в языке запросов 1С нет.
Тем более там в каментах говорят, что часто ЛЕФТ ДЖОй уделывает НОТ ЕКЗИСТ
11 ptiz
 
15.03.17
13:20
(0) Проверил на своей базе.
Вариант "Не В (Запрос... " - на порядок быстрее первого
12 Naf2017
 
15.03.17
13:27
(10) EXIST заменяется IN почти всегда
13 Naf2017
 
15.03.17
13:28
(11) у меня медленнее немного
14 Naf2017
 
15.03.17
13:29
предлагаю МЕДЛЕННЫЙ и ИЗВРАЩЕННЫЙ вариант:

ВЫБРАТЬ
    СпрНоменклатура.Ссылка,
    0 КАК Флаг
ПОМЕСТИТЬ ТЗ
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура

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

ВЫБРАТЬ
    ТоварыНаСкладахОбороты.Номенклатура,
    1
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Обороты КАК ТоварыНаСкладахОбороты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТЗ.Ссылка
ИЗ
    ТЗ КАК ТЗ

СГРУППИРОВАТЬ ПО
    ТЗ.Ссылка

ИМЕЮЩИЕ
    СУММА(ТЗ.Флаг) = 0
15 ptiz
 
15.03.17
13:33
(13) Да, много зависит от конкретной базы. Поэтому я бы не был так категоричен, как (1).
16 youalex
 
15.03.17
13:36
(10) вместо EXISTS можно использовать  1 В (ВЫБРАТЬ ПЕРВЫЕ 1 1 ИЗ )
17 svsvsv
 
15.03.17
13:39
Конструкция "НЕ В ()" часто является проблемой проблемой производительности, для повышения производительности приходилось переписывать даже типовые запросы (в частности, зарплатные)
18 RomanYS
 
17.03.17
12:55
Потестил на текущей базе (SQL). "Ужасный" запрос стабильно выигрывает у хорошего 5-10%:
Левое с таблицей регистра 41
Левое с таблицей оборотов регистра 39
НЕ В с таблицей регистра 38
НЕ В с таблицей регистра (различные) 38
НЕ В с таблицей оборотов регистра 38
Время в мс.
19 Naf2017
 
17.03.17
14:05
(18) видимо объемы слабые, база серверная?
20 RomanYS
 
17.03.17
14:28
(19) база серверная, небольшая.
Справочник ~15 тыс
Регистр ~100 тыс
21 xxTANATORxx
 
17.03.17
14:56
(0)если количество записей регистра много больше записей справочника серий
я бы пробовал так
во времянку выбрать все различные серии из партий товаров
в основном запросе соединить справочник серий и времянку по по условию есть NULL