Имя: Пароль:
1C
1С v8
Медленно выполняется запрос
,
0 Kaukass
 
13.05.15
11:11
Как можно оптимизировать данный запрос, что бы быстрее выполнялся?

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

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
    СУММА(ТоварыНаСкладахОстаткиИОбороты.КоличествоКонечныйОстаток) КАК КоличествоКонечныйОстаток,
    УстановкаЦенНоменклатурыТовары.Цена,
    ЦеныПредыд.Цена КАК Цена1
ИЗ
    РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&Дата1, &Дата1, День, , ) КАК ТоварыНаСкладахОстаткиИОбороты
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.УстановкаЦенНоменклатуры.Товары КАК УстановкаЦенНоменклатурыТовары
        ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура = УстановкаЦенНоменклатурыТовары.Номенклатура
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЦеныПредыд КАК ЦеныПредыд
        ПО ТоварыНаСкладахОстаткиИОбороты.Номенклатура = ЦеныПредыд.Номенклатура
ГДЕ
    ТоварыНаСкладахОстаткиИОбороты.Склад = &Склад
    И УстановкаЦенНоменклатурыТовары.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2
    И УстановкаЦенНоменклатурыТовары.ТипЦен = &ТипЦен

СГРУППИРОВАТЬ ПО
    УстановкаЦенНоменклатурыТовары.Ссылка.Дата,
    ТоварыНаСкладахОстаткиИОбороты.Номенклатура,
    УстановкаЦенНоменклатурыТовары.Цена,
    ЦеныПредыд.Цена
______________________
1 patria0muerte
 
13.05.15
11:13
А в чем суть запроса то? На кой он впился тебе?
2 Зеленый пень
 
13.05.15
11:14
Жескач
3 RomanYS
 
13.05.15
11:15
Все условия в параметры виртуальных таблиц
4 Зеленый пень
 
13.05.15
11:16
1. Сначала получи список товаров для отбора
(из Документ.УстановкаЦенНоменклатуры.Товары ) и поместит во врем таблицу
2. Этот список используй для условий вирт.таблиц.
Склад и тип цен - тоже используй как условие внутри вирт.таблиц
5 bodri
 
13.05.15
11:17
(0) здесь думаю нужно сделать всё наоборот, сначала собрать документы изменения цен (вложеный запрос), а потом через соединение выбрать прошлые цены. Так должен работать быстрее.
6 RomanYS
 
13.05.15
11:19
По всей видимости кроме того, что запрос тормозит, он еще выдает не то, что нужно ТС
7 Kaukass
 
13.05.15
11:21
(4), (5) - спасибо.
(6) - выдает правильно.
(1) Работаю у мадам Троекуровой, спорить с которой - дело безполезное. В УТ оптовые склады и количественный учет, а она стала требовать с завмагов товарный отчет, как в рознице. В этом запросе (если правильно поставил себе задачу) будет сумма переоценки за день.
8 D_E_S_131
 
13.05.15
11:29
(1) "Что делает запрос или как тяжело живется серверу 1С"
1. Выбирает все товары с ценами.
2. Отсеивает из выбранных товаров ненужные типы цен (по принципу "что не съем, то понадкусываю").
3. Выбирает все обороты товаров за день, по которым когда-либо происходили установки цен, а так же есть цены на товар (не факт же, что Установка цен установит какую-то цену).
4. Потом (именно "потом", а никак не раньше) проверяется, а входит ли установка цен в заданный период.
5. Так же мы сейчас понимаем, что нам нужны не все установки цен, а только по определенному типу цен.
6. Потом мы все это группируем, потому как в запрос нам навыбирал кучу разной %рени и у мадам Троекуровой от этого мигрень начинается как она все это в отчете видит.

Как-то так...
9 D_E_S_131
 
13.05.15
11:31
(7) А какая периодичность у регистра "ЦеныНоменклатуры"?
10 D_E_S_131
 
13.05.15
11:43
А вообще даже теория вопроса интересна.
1. Вот было у меня 2 товара:
Т1 - кол-во 10 шт - цена 100 руб - на сумму 1000 руб
Т2 - кол-во 20 шт - цена 200 руб - на сумму 4000 руб
----------------------------------------------------
Итого - 5000 руб

2. Преоцениваю:
Т1 - 120 руб
Т2 - 180 руб

3. За день продают:
Т1 - 4 шт - остаток 6 шт - на сумму 720 руб
Т2 - 12 шт - остаток 8 шт - на сумму 1440 руб
---------------------------------------------------
Итого - 2160

И вот как тут будет считаться "Сумма переоценки за день"?
11 bodri
 
13.05.15
11:52
(10) по остатку на конец дня
Новые цены
Т1 - 6 - 720
Т2 - 8 - 1440
Итого - 2160

Старые цены
Т1 - 6 - 600
Т2 - 8 - 1600
Итого - 2200

Переоценка -40

Ну, как-то так
12 Kaukass
 
13.05.15
11:58
(9) У цен номенклатуры в параметрах виртуальной таблицы нету Периодичности. Только параметр Период
13 bodri
 
13.05.15
11:59
(12) в (9) имелось ввиду скорей всего периодичность самого регистра сведений, а не виртуальной таблицы
14 Kaukass
 
13.05.15
12:00
(13) тогда  - День.
15 Kaukass
 
13.05.15
12:04
Запрос у меня получился веселый - буду исправлять.
16 AlexITGround
 
13.05.15
12:09
(13) "периодичность самого регистра сведений, а не виртуальной таблицы"

:)
17 D_E_S_131
 
13.05.15
12:11
(15) Тебе обязательно это все делать одним запросом?
Просто предварительное получение остатков, выгрузка их в массив, а потом уже получение цен по ним на текущую дату и предыдущую может быть гораздо эффективнее.
18 RomanYS
 
13.05.15
12:19
(0) ты в курсе, что таблица ОстаткиИобороты не даст записей с остатками за те дни , когда не было движений по товору?
19 Aloex
 
13.05.15
12:24
(17) можно и одним запросом.
20 D_E_S_131
 
13.05.15
12:26

Процедура СуммаТоварнойПереоценки(ДатаОтчета, СкладОтчета)

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

КонецПроцедуры
21 D_E_S_131
 
13.05.15
12:27
(19) Вопрос только в "цене" этого решения.
22 anaed
 
13.05.15
12:33
(20) что за изврат?
(21) вы хотите сказать это отработает быстрее чем просто помещение остатков во временную таблицу?
23 Crush
 
13.05.15
12:33
(20) А какой эффект достигается лишним обращением к серверу?
Когда таблицу "ВТ_Остатки" можно получить сразу в результирущем запросе.
24 anaed
 
13.05.15
12:40
(20) уверен быстрее будет
"ВЫБРАТЬ
|    ТоварыНаСкладахОстатки.Номенклатура,
|    ТоварыНаСкладахОстатки.КоличествоОстаток
|ПОМЕСТИТЬ втОстатки
|ИЗ
|    РегистрНакопления.ТоварыНаСкладах.Остатки(&ТекДата, Склад = &СкладОтчета) КАК ТоварыНаСкладахОстатки
|
|ИНДЕКСИРОВАТЬ ПО
|    ТоварыНаСкладахОстатки.Номенклатура
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    ВТ_Остатки.Номенклатура,
|    ВТ_Остатки.КоличествоОстаток,
|    ВТ_Остатки.КоличествоОстаток * ЕСТЬNULL(ПрошлыеЦены.Цена, 0) - ВТ_Остатки.КоличествоОстаток * ЕСТЬNULL(НынешниеЦены.Цена, 0) КАК СуммаПереоценки
|ИЗ
|    ВТ_Остатки КАК ВТ_Остатки
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
|                ДОБАВИТЬКДАТЕ(&ТекДата, ДЕНЬ, -1),
|                ТипЦен = &ТипЦен
|                    И Номенклатура В
|                        (ВЫБРАТЬ
|                            таблица.Номенклатура
|                        ИЗ
|                            втОстатки КАК таблица)) КАК ПрошлыеЦены
|        ПО ВТ_Остатки.Номенклатура = ПрошлыеЦены.Номенклатура
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(
|                &ТекДата,
|                ТипЦен = &ТипЦен
|                    И Номенклатура В
|                        (ВЫБРАТЬ
|                            таблица.Номенклатура
|                        ИЗ
|                            втОстатки КАК таблица)) КАК НынешниеЦены
|        ПО ВТ_Остатки.Номенклатура = НынешниеЦены.Номенклатура";
25 Kaukass
 
13.05.15
12:46
(17) сначала так и хотел сделать. Только не в массивы а в таблицы значений. Но подумал, что это не "модный" способ решения задачи. В досовском фоксе так бы и сделал.
(18) Не знал и потому не учел этот ньюанс
26 ЧеловекДуши
 
13.05.15
12:51
(0) А зачем там Где?
Когда ты уже отбор делаешь по ВНУТРЕННЕЕ СОЕДИНЕНИЕ
27 Kaukass
 
13.05.15
13:00
(26) После того, как прочитал ответы парней, я и сам думаю, а зачем? Не знал, что склад можно указать в параметрах ВТ
28 D_E_S_131
 
13.05.15
13:44
(22)(23) Попробуйте замерить сколько займет времени 2 запуска запроса и сколько будет отрабатывать "Выбор ..Когда" в параметрах вирт.таблицы, а потом расскажите.
29 D_E_S_131
 
13.05.15
13:46
(25) За то "модный" оказался более тормознутым?
30 D_E_S_131
 
13.05.15
13:47
(27) Если кол-во позиций номенклатуры измеряется десятками, то можешь сделать одним запросом как anaed написал.
31 samozvanec
 
13.05.15
14:08
РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты(&Дата1, &Дата1, День, , )

что он вообще выбирает? одну секунду?
32 samozvanec
 
13.05.15
14:11
(0) "сумма переоценки за день" при чем тут вообще товародвижение?
33 Kaukass
 
13.05.15
14:32
(32) - а что тогда при чем? Какой регистр?
(31) - хотел взять остаток на конец дня. Подумал, что не критично, если даже выбирать одну секунду.
34 Aloex
 
13.05.15
14:34
(21) и какова цена?
35 samozvanec
 
13.05.15
14:51
(33) зачем остатки и обороты, если тебе только на конец дня? выбери изменение цен, по этим товарам остаток на конец дня. ну или на начало, цена же действует с начала дня. и помножь
36 samozvanec
 
13.05.15
14:53
а еще ведь скидки/наценки бывают
37 samozvanec
 
13.05.15
14:55
(33) ОстаткиИОбороты очень странная таблица, поговаривают, что если выбрать два раза остатки и еще обороты, и соединить, то будет быстрее работать
38 D_E_S_131
 
13.05.15
15:40
(34) На тысячах номенклатурах на остатках и в ценах — серьезный "просад" по производительности.
39 hhhh
 
13.05.15
16:14
(37) она заточена под периоды месяц, квартал. Тогда быстро. А если день как у автора, то естественно будет тормозить.
40 Kaukass
 
13.05.15
18:32
Благодарю всех откликнувшихся.
Основная теорема систематики: Новые системы плодят новые проблемы.