Имя: Пароль:
1C
 
Поясните по производительности запроса
0 Fuas4
 
11.08.16
20:35
Господа, УТ 10.3 есть простенький запрос:

ВЫБРАТЬ
    ТабТоваров.Номенклатура,
    ТабТоваров.Артикул
ПОМЕСТИТЬ ВТ
ИЗ
    &ТабТоваров КАК ТабТоваров
;

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


Запускаю его одной и той же кнопкой несколько раз подряд, получает он одни и теже данные (точно), но иногда 20 секунд, а иногда - 420 секунд (числа разные все время. может и 200 секунд быть, максимум был несколько тысяч). База файловая, но запускал на серверной (PostgreSQL), там тоже самое. ТиИ делал, итоги пересчитывал.
В чем может быть проблема? Платформа 8.3.8.1861
1 shuhard
 
11.08.16
20:37
(0)[ВЫБРАТЬ
    ТабТоваров.Номенклатура,
    ТабТоваров.Артикул
ПОМЕСТИТЬ ВТ
ИЗ
    &ТабТоваров КАК ТабТоваров]
ни о чем
2 Fuas4
 
11.08.16
20:38
(1) это я так сделал,потому что если я тупо к остаткам левым соединенением привязываю срез последних цен, то окончания получения данных я дождаться не могу. А так сначала в ТАбТоваров получаю остаток, потом к нему вяжу цены.
3 Fuas4
 
11.08.16
20:43
и если просто срез последних цен получить по списку номенклатуры (Номенклатура В (&СписокНоменклатуры), то также долго отрабатывается.
4 тарам пам пам
 
11.08.16
21:07
(0) по производительности запросов нужно в общем случае профайлер СУБД смотреть, другим способом ты точного ответа не получишь.

Если телепатировать - можно попробовать для регистра разрешить использовать итоги среза последних, если есть возможность конфу менять (вроде в 8.3.6 добавили, если память не изменяет).

Сама платформа 8.3.8 на мой взгляд еще сырая (чего только стоят поломанные и до сих пор не починенные РИБ) - можно попробовать на предыдущих версиях.

Можно еще попробовать "развернуть" запрос - т. е. соединить напрямую с таблицей регистра и собрать срез последних самому. Хотя обычно платформа сама адекватно это делает.

Если ВТ достаточно большая (>10 тыс позиций), можно попробовать для нее добавить индекс по номенклатуре.
5 CHerypga
 
11.08.16
21:07
В регистре ЦеныНоменклатуры Номенклатура индексируется?
6 Fuas4
 
11.08.16
21:12
(5) Нет. Индексировать в значении "Не индексировать" и не доступно для изменения. Кстати, почему?
(4) Конфу можно менять, но у конфы режим совместимости 8.2.13. Не чревато ли до 8.3.6 поднимать?
7 Fuas4
 
11.08.16
21:15
Недоступно, потому что стоит галка "Ведущее". Ведущее кроме возможности перехода в список цен из элемента справочника что-то дает?
8 H A D G E H O G s
 
11.08.16
21:17
(7) индексирование дает
9 тарам пам пам
 
11.08.16
21:18
(6) "Ведущее" всегда автоматом индексируется, почитай ИТС по поводу индексов http://its.1c.ru/db/metod8dev/content/1590/hdoc
Менять режим совместимости для включения итогов регистра сведений не нужно, просто включи его и все. По крайней мере у меня с режимом совместимости 8.2.16 дает включить.
10 тарам пам пам
 
11.08.16
21:20
(9) UPD проверил с режимом 8.2.13 - тоже итоги включаются без проблем.
11 Fuas4
 
11.08.16
21:22
(9) ога, про ведущее "понял". Странно, что для ведущего измерения стоит "Не индексировать", хотя таким как я было бы понятнее. если бы при установке ведущего автоматом значение изменялось бы на "Индексировать", но да ладно. Галку тоже увидел, сейчас с ней погоняю регистр
12 CHerypga
 
11.08.16
21:22
(7) ну раз так, наугад можно только предположить что Номенклатура может быть составного типа например в ТабТоваров. Остальное уже в (4) написано
13 H A D G E H O G s
 
11.08.16
21:22
СрезПоследних вынести в отдельную ВТ, в параметры добавить отбор по номенклатуре (если ее количество много меньше записей регистра), индексировать Вт не надо.

Смотреть план запроса
14 Fuas4
 
11.08.16
21:25
(12) не, номенклатура всегда номенклатура. ТАм в ТабТоваров - выгрузка из регистра Остатки на складах. А вообще, попробую завтра все же объединить таблицы в один запрос и сделать как в (13)
15 sergeystav
 
11.08.16
21:33
Помести цены из регистра с отбором по ВТ  во временную таблицу
,а потом следующим запросом ВТ соединяй с временной таблицей цен. Этим ты избавишь планировщик запроса от разбора левого соединения ВТ с виртуальной таблицей цен.
16 sergeystav
 
11.08.16
21:34
блин уже было в (13)
17 Fuas4
 
11.08.16
21:38
(10) Установка галки сузила диапазон времени выполнения запроса до 1,2 - 6 секунд. Это магия, большое спасибо. Но теперь я вижу, что и вот такой запрос выполняется от 12 до 71 секунды. Это я переживу, но может и тут какая магическая галка есть?
ВЫБРАТЬ
    ТоварыНаСкладахОстатки.Номенклатура,
    ТоварыНаСкладахОстатки.КоличествоОстаток - ЕСТЬNULL(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
    ТоварыНаСкладахОстатки.Склад,
    ТоварыНаСкладахОстатки.Номенклатура.Артикул КАК Артикул,
    ТоварыНаСкладахОстатки.Склад.Код
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки(
            ,
            Номенклатура В ИЕРАРХИИ (&НоменклатураСписок)
                И Склад В (&СписСкладов)
                И НЕ Склад.НеВыгружатьНаСайт) КАК ТоварыНаСкладахОстатки
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки КАК ТоварыВРезервеНаСкладахОстатки
        ПО ТоварыНаСкладахОстатки.Номенклатура = ТоварыВРезервеНаСкладахОстатки.Номенклатура
            И ТоварыНаСкладахОстатки.Склад = ТоварыВРезервеНаСкладахОстатки.Склад
18 Fuas4
 
11.08.16
21:40
И вообще, вопрос ко всем отписавшимся, вы вот это все где узнали? Я программирую скоро 5 лет и, как мне казалось, делаю это достаточно хорошо, но вот только что я ощутил острую необходимость тоже знать то, что вы знаете о индексах, срезах и итогах
19 Zamestas
 
11.08.16
21:47
(18) Букварь есть толстый на эту тему.
20 Fuas4
 
11.08.16
21:50
(19) как называется?
21 H A D G E H O G s
 
11.08.16
22:02
(17) все не правильно.
22 Fuas4
 
11.08.16
22:03
(21) как правильно?
23 тарам пам пам
 
11.08.16
22:06
(17) Зачем обратно-то все в один запрос объединил? Тебе же наоборот советовали по разным врем. таблицам все разбить, а потом уже соединять. Ну и "В ИЕРАРХИИ" тоже может подтормаживать.

(18) Опыт примерно те же 5 лет, самую основу узнал из 1совских курсов по спецу по платформе; по индексам - когда-то хотелось эксперта взять, энтузиазма не хватило, но знания какие-то остались. По флажку с итогами - просто слежу за тем, что нового в платформе появляется. По частым причинам низкой производительности запросов вот тут хорошая статья есть, если доступ есть: http://kb.1c.ru/articleView.jsp?id=44
24 sergeystav
 
11.08.16
22:07
"ТоварыНаСкладахОстатки.Номенклатура.Артикул"
я бы не добирался до реквизита через 2 точки, а соединился со справочником и из него добрался до Артикула, просто не хочется доверять это платформе.

"Номенклатура В ИЕРАРХИИ (&НоменклатураСписок)"
лучше "НоменклатураСписок" поместить во временную таблицу и использовать "Номенклатура В  (ВЫБРАТЬ Номенклатура ИЗ ВремНоменклатураСписок)"

"Склад В (&СписСкладов)"
это тоже через временную таблицу. Потому как эта конструкция на сервере разложется в такую "Склад В (Склад1 или Склад2 или Склад3...)" в результате не будет использоваться индекс
25 Zamestas
 
11.08.16
22:10
26 Fuas4
 
11.08.16
22:12
(23) Обратно не объединял. ТабТоваров из первого запроса - это как раз результат вот этого запроса. За инфу спасибо, доступа нет, но где почитать - найду. Теперь стимул есть спеца по платформе получить.
(24) Я так понял, чем больше запрос, тем быстрее он работает :)
Всем спасибо за помощь, завтра на свежую голову все написаное еще раз осмыслю
27 H A D G E H O G s
 
11.08.16
22:13
ВЫБРАТЬ
    Номенклатура.Ссылка,
    Номенклатура.Артикул
ПОМЕСТИТЬ СписокНоменклатур
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ(&СписокНоменклатур)
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Склады.Ссылка,
    Склады.Код
ПОМЕСТИТЬ СписокСкладов
ИЗ
    Справочник.Склады КАК Склады
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ТоварыНаСкладахОстатки.Номенклатура,
    ТоварыНаСкладахОстатки.КоличествоОстаток - ЕСТЬNULL(ТоварыВРезервеНаСкладахОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
    ТоварыНаСкладахОстатки.Склад,
    СписокСкладов.Код КАК СкладКод,
    СписокНоменклатур.Артикул КАК Артикул
ИЗ
    СписокНоменклатур КАК СписокНоменклатур
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(, ) КАК ТоварыНаСкладахОстатки
            ВНУТРЕННЕЕ СОЕДИНЕНИЕ СписокСкладов КАК СписокСкладов
            ПО СписокСкладов.Ссылка = ТоварыНаСкладахОстатки.Склад
            ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыВРезервеНаСкладах.Остатки КАК ТоварыВРезервеНаСкладахОстатки
            ПО ТоварыНаСкладахОстатки.Склад = ТоварыВРезервеНаСкладахОстатки.Склад
                И ТоварыНаСкладахОстатки.Номенклатура = ТоварыВРезервеНаСкладахОстатки.Номенклатура
        ПО СписокНоменклатур.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
28 H A D G E H O G s
 
11.08.16
22:14
(24) "Потому как эта конструкция на сервере разложется в такую "Склад В (Склад1 или Склад2 или Склад3...)" в результате не будет использоваться индекс"

глупости
29 тарам пам пам
 
11.08.16
22:20
(27) Параметры вирт. таблиц зря не задал. Платформа же вирт. таблицы в подзапросы разворачивает. Не факт, что оптимизатор СУБД осилит наложить отбор сразу внутри вложенного запроса, а не получит вообще все остатки и только потом будет их отбирать.
30 H A D G E H O G s
 
11.08.16
22:28
(29) оптимизатор справляется.
31 aleks_default
 
12.08.16
09:46
(27) НЕ Склад.НеВыгружатьНаСайт забыл в условие запроса по выбору складов добавить
32 Fuas4
 
12.08.16
10:07
(31) Ну такие то вещи я способен сам учесть :)
Тащемта, все получилось, Запрос к номенклатуре вынес в отдельный запрос и использую менеджер временных таблиц, т.к. далее в коде есть еще один запрос с использованием этой же конструкции В ИЕРАРХИИ. Результат  - запрос к номенклатуре от 2х до 17 секунд, основной запрос 0.3-0.5 секунды. Это более чем приемлемое для меня время. Интересно, конечно, почему простейший запрос с использованием В ИЕРАРХИИ может по скорости отличаться в 8 раз, но да ладно.
Если код кому интересен:

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

http://1clancer.ru/article/operator_v_ierarkhii_v_zaprose_764
34 Fuas4
 
12.08.16
10:43
(33) интересно, почему он одни и те же данные одним и тем же запросом в одной и той же базе, где кроме меня никого нет, может выбирать по разному.
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.