Имя: Пароль:
1C
1С v8
Замедление запроса при перестановке местами Левых соединений
,
0 Sasha_H
 
22.01.14
12:52
Всем привет. Есть запрос. Задача его получить цены и остатки товаров которые входят в определенный бренд.

ВЫБРАТЬ
    Бренды.Бренд
ПОМЕСТИТЬ БрендыКаталога
ИЗ
    Справочник.ТорговыеАгенты.Бренды КАК Бренды
ГДЕ
    Бренды.Ссылка = &ТорговыйАгент
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    МАКСИМУМ(ЕСТЬNULL(ЦеныНоменклатуры.Цена / ЦеныНоменклатуры.ЕдиницаИзмерения.Коэффициент * СпрНоменклатура.ЕдиницаХраненияОстатков.Коэффициент, 0)) КАК Цена,
    СУММА(ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резерв.КоличествоОстаток, 0)) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены) КАК ЦеныНоменклатуры
        ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры.Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                ,
                Склад В
                    (ВЫБРАТЬ
                        СоставГруппДоступностиСкладов.Склад
                    ИЗ
                        РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                    ГДЕ
                        СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Остатки
        ПО СпрНоменклатура.Ссылка = Остатки.Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
                ,
                Склад В
                    (ВЫБРАТЬ
                        СоставГруппДоступностиСкладов.Склад
                    ИЗ
                        РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                    ГДЕ
                        СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Резерв
        ПО СпрНоменклатура.Ссылка = Резерв.Номенклатура
ГДЕ
    СпрНоменклатура.Бренд В
            (ВЫБРАТЬ
                БрендыКаталога.Бренд
            ИЗ
                БрендыКаталога КАК БрендыКаталога)

СГРУППИРОВАТЬ ПО
    СпрНоменклатура.Ссылка

Этот запрос отрабатывает за 340 мс - шикарно. НО!!!! Если я в этом запросе таблицу Цен и ее соединение поставлю вниз или вовсе выброшу

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены) КАК ЦеныНоменклатуры
        ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры.Номенклатура

Запрос тогда выходит за 1.6 секунды. Непонимаю как так? Количество результирующих данных одинаково!
1 Sasha_H
 
22.01.14
12:54
1С:Підприємство 8.2 (8.2.18.102)
2 zladenuw
 
22.01.14
13:06
а если второй запрос поместить во временную а уже с временной делать соединение ?
3 Мыш
 
22.01.14
13:06
План запроса разный. В скуле отслеживай.
4 Sasha_H
 
22.01.14
13:10
ВЫБРАТЬ
    Бренды.Бренд
ПОМЕСТИТЬ БрендыКаталога
ИЗ
    Справочник.ТорговыеАгенты.Бренды КАК Бренды
ГДЕ
    Бренды.Ссылка = &ТорговыйАгент
;

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

СГРУППИРОВАТЬ ПО
    СпрНоменклатура.Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Каталог.Номенклатура,
    ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резерв.КоличествоОстаток, 0) КАК Остаток
ИЗ
    Каталог КАК Каталог
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                ,
                Номенклатура В
                        (ВЫБРАТЬ
                            Каталог.Номенклатура
                        ИЗ
                            Каталог КАК Каталог)
                    И Склад В
                        (ВЫБРАТЬ
                            СоставГруппДоступностиСкладов.Склад
                        ИЗ
                            РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                        ГДЕ
                            СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Остатки
        ПО Каталог.Номенклатура = Остатки.Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
                ,
                Номенклатура В
                        (ВЫБРАТЬ
                            Каталог.Номенклатура
                        ИЗ
                            Каталог КАК Каталог)
                    И Склад В
                        (ВЫБРАТЬ
                            СоставГруппДоступностиСкладов.Склад
                        ИЗ
                            РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                        ГДЕ
                            СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Резерв
        ПО Каталог.Номенклатура = Резерв.Номенклатура

ПОХЕР- 1.2 секунды
5 Sasha_H
 
22.01.14
13:11
(3) я понимаю что разный. Но это дибило 1совцо. Идут левые соединения. Теперь что выходит если мне надо быстрее получить остатки то делать еще соединения к таблдице цен, что за бип.....
6 Classic
 
22.01.14
13:19
(0)
Меня терзают смутные сомнения.
Может у тебя 0.3 кэшированы, а 1.6 - нет?
7 Classic
 
22.01.14
13:21
(4)
А где условие на бренд?
8 Sasha_H
 
22.01.14
13:21
(7)
ГДЕ
    СпрНоменклатура.Бренд В
            (ВЫБРАТЬ
                БрендыКаталога.Бренд
            ИЗ
                БрендыКаталога КАК БрендыКаталога)
9 Sasha_H
 
22.01.14
13:22
(6) это копия базы. тут я один. перезаходил в 1с. тоже самое.
10 Sasha_H
 
22.01.14
13:23
(3) я не смотрел но все к этому сводится. но просто бред какой-то выходит.
11 vhl
 
22.01.14
13:24
(0) Что значит "поставлю вниз"? Это как?
И что значит "выброшу" ? А если выбросить все кроме брендов, то вообще будет 0.01с, круто же? Только хрень полная.
12 ptiz
 
22.01.14
13:24
(0) Покажи второй вариант запроса, более быстрый и без выкидывания таблицы.
13 Classic
 
22.01.14
13:26
(11)
Поддержую.
(0)
Выложи, какой запрос получается после "выброшу".
И кстати данный запрос лучше вообще без соединений делать. Объединение с дальнейшей группировкой отрулит
14 Sasha_H
 
22.01.14
13:26
(0) и есть быстры вариант запроса.
15 Sasha_H
 
22.01.14
13:28
вот медленей работает без цен. Если сюда прицепить цены. И главное в место после КАК СпрНоменклатура - то запрос летает.

ВЫБРАТЬ
    Бренды.Бренд
ПОМЕСТИТЬ БрендыКаталога
ИЗ
    Справочник.ТорговыеАгенты.Бренды КАК Бренды
ГДЕ
    Бренды.Ссылка = &ТорговыйАгент
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резерв.КоличествоОстаток, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                ,
                Склад В
                    (ВЫБРАТЬ
                        СоставГруппДоступностиСкладов.Склад
                    ИЗ
                        РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                    ГДЕ
                        СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Остатки
        ПО СпрНоменклатура.Ссылка = Остатки.Номенклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
                ,
                Склад В
                    (ВЫБРАТЬ
                        СоставГруппДоступностиСкладов.Склад
                    ИЗ
                        РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                    ГДЕ
                        СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Резерв
        ПО СпрНоменклатура.Ссылка = Резерв.Номенклатура
ГДЕ
    СпрНоменклатура.Бренд В
            (ВЫБРАТЬ
                БрендыКаталога.Бренд
            ИЗ
                БрендыКаталога КАК БрендыКаталога)
16 Sorm
 
22.01.14
13:32
(0) Бывает. Оптимизатор другой план запроса строит, использует другие индексы.
17 Sorm
 
22.01.14
13:33
(15) "ГДЕ
    СпрНоменклатура.Бренд В
            (ВЫБРАТЬ
                БрендыКаталога.Бренд
            ИЗ
                БрендыКаталога КАК БрендыКаталога)"
Неправильно. Делай внутреннее соединение в запросе и проиндексируй временную таблицу по полям соединений.
18 Classic
 
22.01.14
13:35
(17)
Если соединенять, то надо в временнной сразу РАЗЛИЧНЫЕ писать.
А индексирование зачем? Левую индексировать без толку
(0)
Я не смог продублировать проблемму. У меня без цен на порядок быстрее делается.
Конечно условие на бренды и группу доступности убрал
19 Sorm
 
22.01.14
13:38
(18) Ну, можно и различные писать. Я же не знаю, уникальные там данные у него или нет.
Индексирование временной таблицы зачем?:) Ну как бы быстрей произойдет соединение однако...
20 Classic
 
22.01.14
13:40
(19)
При индексировании левой соединение врядли быстрее произойдет :)
У него похоже фигня какая-то с индексированием правых происходит. В ДТшках
21 Sasha_H
 
22.01.14
13:41
(17)
Дольше отрабатывает в таком случае

ВЫБРАТЬ
    Бренды.Бренд КАК Бренд
ПОМЕСТИТЬ БрендыКаталога
ИЗ
    Справочник.ТорговыеАгенты.Бренды КАК Бренды
ГДЕ
    Бренды.Ссылка = &ТорговыйАгент

ИНДЕКСИРОВАТЬ ПО
    Бренд
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СпрНоменклатура.Родитель КАК Группа,
    СпрНоменклатура.Ссылка КАК Номенклатура,
    СпрНоменклатура.Наименование,
    СпрНоменклатура.Бренд.Наименование КАК Производитель,
    СпрНоменклатура.БазоваяЕдиницаИзмерения КАК ЕдиницаИзмерения,
    СпрНоменклатура.ЦеноваяГруппа,
    СпрНоменклатура.ЦеноваяГруппа.Наименование КАК ЦеноваяГруппаНаименование,
    МАКСИМУМ(ЕСТЬNULL(ЦеныНоменклатуры.Цена / ЦеныНоменклатуры.ЕдиницаИзмерения.Коэффициент * СпрНоменклатура.ЕдиницаХраненияОстатков.Коэффициент, 0)) КАК Цена,
    СУММА(ЕСТЬNULL(Остатки.КоличествоОстаток, 0) - ЕСТЬNULL(Резерв.КоличествоОстаток, 0)) КАК Остаток
ИЗ
    БрендыКаталога КАК БрендыКаталога
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО БрендыКаталога.Бренд = СпрНоменклатура.Бренд
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ТипЦен = &ТипЦены) КАК ЦеныНоменклатуры
            ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры.Номенклатура
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                    ,
                    Склад В
                        (ВЫБРАТЬ
                            СоставГруппДоступностиСкладов.Склад
                        ИЗ
                            РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                        ГДЕ
                            СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Остатки
            ПО СпрНоменклатура.Ссылка = Остатки.Номенклатура
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки(
                    ,
                    Склад В
                        (ВЫБРАТЬ
                            СоставГруппДоступностиСкладов.Склад
                        ИЗ
                            РегистрСведений.СоставГруппДоступностиСкладов КАК СоставГруппДоступностиСкладов
                        ГДЕ
                            СоставГруппДоступностиСкладов.ГруппаДоступности = &ГруппаДоступности)) КАК Резерв
            ПО СпрНоменклатура.Ссылка = Резерв.Номенклатура
        

СГРУППИРОВАТЬ ПО
    СпрНоменклатура.Родитель,
    СпрНоменклатура.Ссылка,
    СпрНоменклатура.Наименование,
    СпрНоменклатура.БазоваяЕдиницаИзмерения,
    СпрНоменклатура.ЦеноваяГруппа,
    СпрНоменклатура.ЦеноваяГруппа.Наименование,
    СпрНоменклатура.Бренд.Наименование
22 Classic
 
22.01.14
13:44
(21)
А если бренды с номенклатурой местами поменять?
Так то конечно долго
23 Sorm
 
22.01.14
13:45
(20) Давай разбирать запрос, однако. Первое - почему номенклатура, которая в конце отбирается по брендам таким интересным способом, не загнана во временную таблицу уже отобранной по брендам и проиндексированной? Зачем системе делать 2 лишних соединения, если она потом строку вообще выкинет из набора?
24 Classic
 
22.01.14
13:46
(23)
Он в (4) уже загнал. Говорит, что не помогает
25 dk
 
22.01.14
13:47
(21) ни хрена се группировок то ...
достаточно по номенклатуре похоже, остальные в МАКС загнать
26 Sorm
 
22.01.14
13:50
(24) Ну а индексы-то где по номенклатуре? Ведь 2 соединения идет.
27 Sasha_H
 
22.01.14
13:57
(25) да не в этом дело. Ну научитесь читать САБЖ. Когда таблица цен идет сразу в соединении - работает быстро! Если Це убрать вообще - работает медлено. Также работает медлено когда соединение по ценам разместить после соединений с остаткми
28 Sasha_H
 
22.01.14
14:01
Видимо в таблице цен он быстренько расчитал их и сам оптимизировал план запроса, получив остатки только определенной номенклатуры.
29 Classic
 
22.01.14
14:02
(27)
Та не, как раз важны эти тонкости.
Убери вообще условие по брендам и сравни два запроса "с ценами" и "без цен"
Потому как есть определнная вероятность, что условие на бренды в одном случае передается в остатки, а в другом - нет
30 dk
 
22.01.14
14:04
1. а через объединения если попробовать?
2. надо сначала фильтр по номенклатуре построить и навпихать этот фильтр в остатки и резервы виртуальные
---
или проблема не "как быстрее", а "почему быстрее"?
31 H A D G E H O G s
 
22.01.14
14:09
Как же это просто - глянуть профайлер.

Особенно когда запрос выполняется на текущую дату.
32 kiruha
 
22.01.14
14:15
(0)
У тебя есть ограничение на номенклатуру - почему в виртуальных не ставишь ?
33 kiruha
 
22.01.14
14:19
ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Ссылка
Поместить ТаблицаВыбираемойНоменклатуры
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
ГДЕ
    СпрНоменклатура.Бренд В
            (ВЫБРАТЬ
                БрендыКаталога.Бренд
            ИЗ
                БрендыКаталога КАК БрендыКаталога)
Индексировать По Ссылка

далее везде в виртуальных ограничение на номенклатуру а не только склад
34 kiruha
 
22.01.14
14:50
Тк такого отбора установлено не было, то оптимизатор ХЗ что ему делать -0 то ли "остатки вычислять" потом цепляться к таблице номенклатуры с ограничением, то ли выбрать номенклатуру с ограничением потом прицепить все Остатки по номенклатуре и далее вычислить последнее значение то ли еще как