Имя: Пароль:
1C
1С v8
Проблема со скоростью выполнения запроса.
,
0 raytan
 
04.03.24
15:02
Стоит старая УПП1.3, платформа 8.2.15.294 и MySQL 2005
В какой то момент стал медленно выполняться отчет на СКД, когда установлен отбор по характеристике. На реальной базе вообще не выполняется. НО если настроить отбор через еще одну точку: вместо ВидПриемки = "Приемка1", установить ВидПриемки.Код = "1", то отчет работает также быстро как и раньше.
Полез смотреть в профайлер. Планы запросов разные и отличаются достаточно сильно. Ну это нормально. Но что вызвало у меня недопонимаение так это то, что для "быстрого" запроса Estimated SubStree Cost для последнего оператора показывает в 300 единиц в событии Showplan xml profile, а для "медленного" ESC = 12 единиц! Но уже в SQL:BatchCompleted "duration" у "быстрого" = 3000, у "медленного" = 300000.
Получается, что SQL Server предполагает, что один запрос будет быстрее другого в 25 раз, а получается совершенно наоборот и разница колоссальна -- 100 раз.
Непонятно, что делать, чтобы запрос работал одинаково хорошо. Может у кого нибудь есть мысли на эту тему или сталкивались с таким?
1 katamoto
 
04.03.24
15:10
Статистику обновить, для начала
2 raytan
 
04.03.24
15:17
Статистика каждую ночь обновляется
3 Волшебник
 
04.03.24
15:18
Покажите запрос
4 raytan
 
04.03.24
15:27
ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ЗначенияСвойствОбъектов.Объект КАК Объект,
    МАКСИМУМ(ВЫБОР
            КОГДА ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип продукции"
                ТОГДА ЗначенияСвойствОбъектов.Значение
            ИНАЧЕ ""
        КОНЕЦ) КАК ТипПродукции,
    МАКСИМУМ(ВЫБОР
            КОГДА ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип продукции"
                ТОГДА ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Значение КАК Справочник.ТипыПродукции).Код
            ИНАЧЕ ""
        КОНЕЦ) КАК ТипПродукцииКод,
    МАКСИМУМ(ВЫБОР
            КОГДА ЗначенияСвойствОбъектов.Свойство.Наименование = "Корпус"
                ТОГДА ЗначенияСвойствОбъектов.Значение
            ИНАЧЕ ""
        КОНЕЦ) КАК Корпус,
    МАКСИМУМ(ВЫБОР
            КОГДА ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип исполнения"
                ТОГДА ЗначенияСвойствОбъектов.Значение
            ИНАЧЕ ""
        КОНЕЦ) КАК ТипИсполнения,
    МАКСИМУМ(ВЫБОР
            КОГДА ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип исполнения"
                ТОГДА ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Значение КАК Справочник.ЗначенияСвойствОбъектов).Код
            ИНАЧЕ ""
        КОНЕЦ) КАК ТипИсполненияКод
ПОМЕСТИТЬ ВТ_Свойства
ИЗ
    РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
    (ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип продукции"
            ИЛИ ЗначенияСвойствОбъектов.Свойство.Наименование = "Корпус"
            ИЛИ ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип исполнения")
    И ЗначенияСвойствОбъектов.Свойство.ПодразделНазначенияСвойства = &ГотоваяПродукция

СГРУППИРОВАТЬ ПО
    ЗначенияСвойствОбъектов.Объект
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
    Продажи.Контрагент,
    Продажи.Номенклатура,
    ВЫБОР
        КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
            ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг)
        КОГДА Продажи.Регистратор ССЫЛКА Документ.КорректировкаЗаписейРегистров
            ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.КорректировкаЗаписейРегистров)
    КОНЕЦ КАК ДокументПродажи,
    Продажи.ДоговорКонтрагента,
    ВЫБОР
        КОГДА Продажи.Номенклатура.ВидНоменклатуры = &ГотоваяПродукция
                ИЛИ Продажи.Номенклатура.ПромХарактер
                    И МЕСЯЦ(Продажи.Период) = МЕСЯЦ(РТУПринятыеВ12П.ПериодПринятия)
                    И ГОД(Продажи.Период) = ГОД(РТУПринятыеВ12П.ПериодПринятия)
            ТОГДА ЕСТЬNULL(Продажи.Количество, 0)
        ИНАЧЕ 0
    КОНЕЦ КАК Количество,
    ВЫБОР
        КОГДА Продажи.Номенклатура.ВидНоменклатуры = &ГотоваяПродукция
                ИЛИ Продажи.Номенклатура.ПромХарактер
                    И МЕСЯЦ(Продажи.Период) = МЕСЯЦ(РТУПринятыеВ12П.ПериодПринятия)
                    И ГОД(Продажи.Период) = ГОД(РТУПринятыеВ12П.ПериодПринятия)
            ТОГДА ЕСТЬNULL(Продажи.СтоимостьВВалюте, 0) - ЕСТЬNULL(Продажи.НДСВВалюте, 0)
        ИНАЧЕ 0
    КОНЕЦ КАК Стоимость,
    ВЫБОР
        КОГДА Продажи.Номенклатура.ВидНоменклатуры = &ГотоваяПродукция
                ИЛИ Продажи.Номенклатура.ПромХарактер
                    И МЕСЯЦ(Продажи.Период) = МЕСЯЦ(РТУПринятыеВ12П.ПериодПринятия)
                    И ГОД(Продажи.Период) = ГОД(РТУПринятыеВ12П.ПериодПринятия)
            ТОГДА ЕСТЬNULL(Продажи.НДСВВалюте, 0)
        ИНАЧЕ 0
    КОНЕЦ КАК НДС
ИЗ
    РегистрНакопления.Продажи КАК Продажи
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Свойства КАК ВТ_Свойства
        ПО Продажи.Номенклатура = ВТ_Свойства.Объект
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РТУПринятыеВ12П КАК РТУПринятыеВ12П
        ПО Продажи.ДокументПродажи = РТУПринятыеВ12П.Документ
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
        ПО (КурсыВалют.Валюта.Код = "840")
            И (НАЧАЛОПЕРИОДА(Продажи.ДатаРеализации, ДЕНЬ) = НАЧАЛОПЕРИОДА(КурсыВалют.Период, ДЕНЬ))
ГДЕ
    (Продажи.Номенклатура.ВидНоменклатуры = &ГотоваяПродукция
            ИЛИ Продажи.Номенклатура.ПромХарактер
                И Продажи.ДокументПродажи.ОтражатьВБухгалтерскомУчете)
    И Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода
    И Продажи.ТипДвиженияПродажи = &ТипДокумента
{ХАРАКТЕРИСТИКИ
    ТИП(Справочник.Номенклатура)
    ВИДЫХАРАКТЕРИСТИК ПланВидовХарактеристик.СвойстваОбъектов
    ПОЛЕКЛЮЧА Ссылка
    ПОЛЕИМЕНИ Наименование
    ПОЛЕТИПАЗНАЧЕНИЯ ТипЗначения
    ЗНАЧЕНИЯХАРАКТЕРИСТИК РегистрСведений.ЗначенияСвойствОбъектов
    ПОЛЕОБЪЕКТА Объект
    ПОЛЕВИДА Свойство
    ПОЛЕЗНАЧЕНИЯ Значение }

(3) Так ?
5 Смотрящий
 
04.03.24
15:32
Мдээээ

ЗначенияСвойствОбъектов.Свойство.Наименование = "Тип продукции" и все подобное заменить на
ЗначенияСвойствОбъектов.Свойство = &СвойствоТипПродукции

СвойствоТипПродукции передавать в запрос как параметр

искать кодом
СвойствоТипПродукции = ПВХ.ТвойПвх.НайтиПоРеквизиту("Имя", "Тип продукции");
Или как там в древности твоей
6 Смотрящий
 
04.03.24
15:32
Для начала
7 Волшебник
 
04.03.24
15:33
(4) запрос дерьмо, отборы дерьмо.

здесь добавьте
РегистрНакопления.Продажи.Обороты(&Нач, &Кон)

левое соединение с курсами валют - отстой
8 lodger
 
04.03.24
15:36
(0) переписать запрос в отчете заново. можно весь отчет заново переделать.
9 Волшебник
 
04.03.24
15:37
(8) Кстати, можно использовать СКД. Говорят, само всё делает.
10 raytan
 
04.03.24
16:29
(5) А что это поменяет ? Тем более с этим запросом проблем нет. Он выполняется достаточно быстро. duration = 200. Отбор на характеристики я накладываю в настройках СКД. Это выглядит как Номенклатура."Характеристика" = что то. И соответственно СКД этот отбор добавляет во второй запрос в пакете.
(7)(8) Запрос отличный. Я умею писать запросы и знаю когда нужно применять виртуальные таблицы. В данной ситуации обращение к физической таблице оправдано. Я несколько урезал данные, которые получаю, чтобы не нагромождать.
Какая проблема насчет курсов ? У нас так организована работа, что на каждый день есть курс. В этой части запрос отрабатывает быстро и данные возвращает верные. Ну может можно было бы хранить еще один реквизит ДатаРеализации без времени и в условии соединения не нужно было бы использовать "НачалоПериода"
(9) Отчет сделан на СКД, но не в этом суть.
11 Волшебник
 
04.03.24
16:30
(10) >> Я умею писать запросы и знаю когда нужно применять виртуальные таблицы.

Что же он у Вас тормозит? Значит не умеете
12 raytan
 
04.03.24
16:44
(11) Мне кажется тут проблема в том, что скл сервер строит неправильный план запроса. И решение должно быть из разряда: обновление статистики (не помогло), переиндексация, очистка кэша и т.д. Эти вещи я пробовал делать и они не сработали.
А то что вы предлагаете. Это не то. Так как буквально неделю назад этот отчет с такими же настройками работал достаточно шустро.
13 arsik
 
гуру
04.03.24
16:49
(12) Я так понимаю это перекидывание проблемы на скуль?
Ну эт не я нахуевертил в запросе, эт скуль неправильно считает.
14 Мимохожий Однако
 
04.03.24
16:49
(12) Нарушена логика. Если отчет работал шустро, а сейчас не шустро, то дело не в отчете, а в железе или СУБД. Опиши характеристики базы данных и то, что вокруг неё.  Может быть и яснее станет
15 arsik
 
гуру
04.03.24
17:00
+(13) Ну и меня будоражат такие конструкции
    ВЫБОР
        КОГДА Продажи.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
            ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РеализацияТоваровУслуг)
        КОГДА Продажи.Регистратор ССЫЛКА Документ.КорректировкаЗаписейРегистров
            ТОГДА ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.КорректировкаЗаписейРегистров)
    КОНЕЦ КАК ДокументПродажи

Где Иначе ? Ну или тогда результат отфильтруй по этим типам.
Потом всякие сравнения с NULL вылетают в трубу. Какой планировщик в таком разберется?
Вот это какой то писдес
    (Продажи.Номенклатура.ВидНоменклатуры = &ГотоваяПродукция
            ИЛИ Продажи.Номенклатура.ПромХарактер
                И <B>Продажи.ДокументПродажи.ОтражатьВБухгалтерскомУчете</B>)
16 Hmster
 
04.03.24
17:13
(0) если есть "скрытые" соединения (обращения через точку), то план выполнения может быть сильно различен для БД разных размеров. Т.е. ты живешь и горя не знаешь, а на следующий день БД еле переваривает запрос.
Да и видимыми соединениями такая штука тоже бывает.

+ не рекомендую в СКД в финальной части запроса использовать группировки. Рано или поздно поимеешь проблем.
17 Волшебник
 
04.03.24
17:28
(12) Отчёт кривой, это видно невооружённым глазом
18 katamoto
 
04.03.24
17:30
(12) Или объем данных мог перевалить за определённый порог, после которого начал строиться другой план, например
19 Смотрящий
 
04.03.24
18:46
(10) Не умеешь писать запросы.
1. 1с плохо работает со строками - но хорошо со ссылками; поэтому Свойство.Наименование = "Тип продукции" меняем на ссылку Свойство = &СвойствоТипПродукции

2. ИЗ
    РегистрНакопления.Продажи КАК Продажи
...
ГДЕ
....

Вызывает полный скан физической таблицы Продажи и только потом наложение условия.
Упрощенно - ты перебираешь миллион записей и выбираешь оттуда сотню.

Гораздо грамотнее накладывать условие в отборе виртуальной таблицы Продажи.Обороты(&Нач, &Кон) - так не перебирается миллион записей а выбираются только те которые удовлетворяют условию (&Нач, &Кон)

3. Ну и ВЫБОР КОГДА ТОГДА ИНАЧЕ КОНЕЦ нужно, по возможности заменять - тяжелая операция...
20 Смотрящий
 
04.03.24
18:56
4. У тебя в ВТ_Свойства уже отобранные объекты имеет смысл второй запрос переделать, накладывая неявный фильтр на Продажи
ИЗ
    ВТ_Свойства КАК ВТ_Свойства
    
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи КАК Продажи
        ПО ВТ_Свойства.Объект = Продажи.Номенклатура
21 Волшебник
 
04.03.24
19:10
Надо больше временных таблиц.
Вначале должны быть самые жёсткие выборки с самыми крутыми отборами.