Имя: Пароль:
1C
1С v8
Запрос из типовой УПП
0 noxxx
 
20.08.13
12:21
В общем модуле УправлениеЗапасамиРасширеннаяАналитика есть функция "ЗаполнитьСуммыВДвижениях".

В ней есть запрос большой, выполнение которого занимает 95% времени проведения документа перемещения. Например, документ со 130 товарами. Проводится 278 секунд, из них 260 - выполнение запроса.

Я разбил запрос на 3 части и выяснил, что самое долгое - это выполнение запроса к регистру цены номенклатуры:

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

Может кто сталкивался с этим? Можно как-нибудь оптимизировать запрос?
1 mehfk
 
20.08.13
12:32
Вот это

И (Номенклатура, ХарактеристикаНоменклатуры) В
                      |                        (ВЫБРАТЬ ОтборПоНоменклатуре.Номенклатура, ОтборПоНоменклатуре.ХарактеристикаНоменклатуры
                      |                        ИЗ ОтборПоНоменклатуре КАК ОтборПоНоменклатуре)
2 noxxx
 
20.08.13
12:35
(1) Что "вот это"?
3 mehfk
 
20.08.13
12:40
оптимизируй
4 Нуф-Нуф
 
20.08.13
12:41
как минимум проиндексируй ОтборПоНоменклатуре
5 mehfk
 
20.08.13
12:43
6 mehfk
 
20.08.13
12:44
7 mehfk
 
20.08.13
12:44
8 mehfk
 
20.08.13
12:44
9 mehfk
 
20.08.13
12:46
10 noxxx
 
20.08.13
12:51
(4) ОтборПоНоменклатуре - это таблица которая получается через "Поместить" в предыдущем запросе. Как её проиндексировать?

(5) Спасибо, попробую.
11 mehfk
 
20.08.13
12:56
(10) Открой запрос в запроснике, увидишь вкладку "Индекс"
12 noxxx
 
20.08.13
13:09
Переделал запрос так:

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

Документ стал проводиться за 10 секунд, но мне кажется что что-то сломалось ...

Цифры все на своих местах.
13 mehfk
 
20.08.13
13:25
По логике должно быть внутреннее. Либо перепиши секцию select

ЦеныНоменклатуры.Номенклатура,
                      |            ЦеныНоменклатуры.ХарактеристикаНоменклатуры,

вот здесь может получиться NULL

и по хорошему другие left join в таком случае надо делать не с ЦеныНоменклатуры а с ОтборПоНоменклатуре
14 noxxx
 
20.08.13
13:32
(13) Я сначала сделал внутреннее, оно отработало за то же время что и селект в селекте.

Потом по аналогии с http://1cexpo.ru/metodiki/20-tipichnye-prichiny-neoptimalnoj-raboty-zaprosov-i-metody-optimizaczii.html переделал в левое.
15 Fragster
 
модератор
20.08.13
13:33
вот это, наверное, тормозит: (Номенклатура, ХарактеристикаНоменклатуры) В
                      |                        (ВЫБРАТЬ ОтборПоНоменклатуре.Номенклатура, ОтборПоНоменклатуре.ХарактеристикаНоменклатуры
                      |                        ИЗ ОтборПоНоменклатуре КАК ОтборПоНоменклатуре)
16 Fragster
 
модератор
20.08.13
13:34
я бы сделал 2 отбора по одному полю, а потом внутреннее соединение результата с таблицей отбора
17 noxxx
 
20.08.13
13:48
(16) А вариант в 12 чем не нравится? Я там еще в ЦеныНоменклатуры.Номенклатура и ЦеныНоменклатуры.ХарактеристикаНоменклатуры, заменил ЦеныНоменклатуры на ОтборПоНоменклатуре чтобы избежать NULL.

Вроде всё работает, и адски быстро.
18 Fragster
 
модератор
20.08.13
13:50
(17) по крайней мере результат внутри временной таблицы - другой.

ну и два соединения с курсами валют можно заменить на один.
19 noxxx
 
20.08.13
14:02
(18) Другой в том плане что у меня будет всё из ОтбораПоНоменклатуре вне зависимости от наличия цен, а изначально только то на что цены в регистре есть?

Потому как в результате результат в движениях документа одинаковый с разницей в скорости 10 секунд против 278.
20 Fragster
 
модератор
20.08.13
14:03
(19) наверняка можно еще выжать
21 noxxx
 
20.08.13
15:10
(20) Это будет следующим этапом :)
22 Gambler99
 
20.08.13
20:40
Вот это еще хорошо бы изменить:

ТипЦен В (
ВЫБРАТЬ
Константы.ТипЦенПлановойСебестоимостиНоменклатуры
ИЗ
Константы КАК Константы
)

на

ТипЦен = &ТипЦенПлановойСебестоимостиНоменклатуры

Соответственно параметр установить:

Запрос.УстановитьПараметр("ТипЦенПлановойСебестоимостиНоменклатуры", глЗначениеПеременной("ТипЦенПлановойСебестоимостиНоменклатуры"));

Прирост производительности возможно будет небольшой, но точно будет, даже на полных правах.
23 Gambler99
 
20.08.13
20:56
Это соединение с константами также создает проблемы со временем выполнения запроса.

См. например:

http://partners.v8.1c.ru/forum/thread.jsp?id=1014641
24 Fragster
 
модератор
20.08.13
21:08
(23) не помню, в каком релизе, но пофикшено. хотя да, все равно "в (&Парам)" почти всегда быстрее "в (выбрать ... из ...)"
25 Fragster
 
модератор
20.08.13
21:09
а вот с "(поле, истина) в (выбрать таб.поле, истина из таб)" - все не так однозначно, бывает что "(поле, истина) в (выбрать таб.поле, истина из таб)" быстрее "поле в (...)"
26 noxxx
 
20.08.13
21:26
(22) Я думал об этом, но решил что прирост будет слишком незначительным на фоне уже получившегося прироста :)
27 Gambler99
 
20.08.13
21:42
(24)

В российском УПП 1.3.43.1 это точно не исправлено.
Я гарантирую это :)
И условие переходит не В (&Парам), а =&Парам
28 Gambler99
 
20.08.13
22:02
(26)

А попробовать?
Даже может на первоначальном запросе.
Интересно просто.

Здесь
http://partners.v8.1c.ru/forum/thread.jsp?id=1014641

пишут, что ускорение от этого было в 3 раза минимум.
29 Fragster
 
модератор
20.08.13
22:05
(27) исправлен тормозной доступ к константам, а не запрос :)
30 Gambler99
 
20.08.13
22:14
(29)

А.
Значит не заметил этого исправления в платформе:(
Ну все равно, не поленился, проверил.
По моим тестам даже сейчас около 5% такое исправление дает.
Это немного, конечно, но все равно есть.
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший