Имя: Пароль:
1C
1С v8
Postgre требует оптимизацию запроса
0 MistaEr
 
07.08.17
12:31
Доброго времени, коллеги!

Перешел на СУБД Postgre SQL (9.6). в связи с тем что SQL Expres поддерживает только до 10 ГБ объема базы. Есть у меня динамический список, с достаточно сложным запросом, с несколькими соединениями. Оптимизировал уже запрос, сколько мог. Но в одном отборе жестко зависает мой список. Отбор добавлен во вкладке Компановка данных - Условия.
НЕ &ОтборПоПотенциальным
    ИЛИ ВЫБОР
        КОГДА 1 В
                (ВЫБРАТЬ ПЕРВЫЕ 1
                    1
                ИЗ
                    РегистрСведений.СтатусыКонтрагентов.СрезПоследних(&ТекущаяДата) КАК СтатусыКонтрагентовСрезПоследних
                ГДЕ
                    СтатусыКонтрагентовСрезПоследних.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКонтрагентов.Потенциальный)
                    И Контрагенты.Ссылка = СтатусыКонтрагентовСрезПоследних.Контрагент)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ
1 MistaEr
 
07.08.17
12:35
Отбор устанавливаю в модуле так:
    Если ОтборПотенциальные  = "Потенциальные" Тогда
        Список.Параметры.УстановитьЗначениеПараметра("ОтборПоПотенциальным", Истина);
    ИначеЕсли ОтборПотенциальные  = "Все" Тогда
        Список.Параметры.УстановитьЗначениеПараметра("ОтборПоПотенциальным", Ложь);
    КонецЕсли;
2 Черный маклер
 
07.08.17
12:38
как запрос работает без
НЕ &ОтборПоПотенциальным ИЛИ
?
3 MistaEr
 
07.08.17
12:42
Не проверял если честно. Тестовая среда пока только на MS SQL, там этот запрос летает. Вечером попробую так, когда все выйдут
4 MistaEr
 
07.08.17
12:43
(2) Получится:
ВЫБОР
    КОГДА 1 В
            (ВЫБРАТЬ ПЕРВЫЕ 1
                1
            ИЗ
                РегистрСведений.СтатусыКонтрагентов.СрезПоследних(&ТекущаяДата) КАК СтатусыКонтрагентовСрезПоследних
            ГДЕ
                СтатусыКонтрагентовСрезПоследних.Статус = &Потенциальный
                И Контрагенты.Ссылка = СтатусыКонтрагентовСрезПоследних.Контрагент)
        ТОГДА ИСТИНА
    ИНАЧЕ ЛОЖЬ
КОНЕЦ
5 MistaEr
 
07.08.17
12:46
А в модуле:

        Если Не Потенциальный Тогда    
                Список.Параметры.Элементы.Найти("Потенциальный ").Использование = Ложь;
        Иначе            
            Список.Параметры.УстановитьЗначениеПараметра("Потенциальный ", Перечисление.СтатусыКонтрагентов.Потенциальный);
        КонецЕсли;
6 MistaEr
 
07.08.17
12:49
Основной запрос соединял ЛЕВЫМ с этим регистром седений, так вообще долго работает
7 Fragster
 
гуру
07.08.17
12:52
Начиная с 8.3.8 можно заменить на пакетный запрос и необязательное левое соединение с временной таблицей с предвыборкой из РС. будет неплохо работать.
8 lodger
 
07.08.17
12:52
И Контрагенты.Ссылка = СтатусыКонтрагентовСрезПоследних.Контрагент

это нормальное условие? что за таблица "Контрагенты"?
вышенабранная ВТ? а где соединение с ней?
9 Fragster
 
гуру
07.08.17
12:53
в настройках компоновки при этом сделать
{ГДЕ ВремТабл.Поле = &Поле} и тогда будет соединение только когда надо
10 Fragster
 
гуру
07.08.17
12:54
ну и выбираться из СРС также будет только когда надо
11 MistaEr
 
07.08.17
12:55
Вот весь запрос:

ВЫБРАТЬ РАЗЛИЧНЫЕ
    Контрагенты.Наименование КАК Наименование,
    Контрагенты.Менеджер КАК Менеджер,
    Контрагенты.а_ДопМенеджер КАК ДопМенеджер,
    Контрагенты.Телефон КАК Телефон,
    ЕСТЬNULL(АктуальныеДоговораКлиентов.ДатаАктивации, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаАктивации,
    ЕСТЬNULL(АктуальныеДоговораКлиентов.ДатаОкончанияСрокаДействия, ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОкончанияСрокаДействия,
    Контрагенты.ЭтоГруппа КАК ЭтоГруппа,
    ВЫРАЗИТЬ(Контрагенты.Комментарий КАК СТРОКА(100)) КАК Комментарий,
    Контрагенты.Ссылка КАК Ссылка,
    ЕСТЬNULL(АктуальныеДоговораКлиентов.Абонемент, ЗНАЧЕНИЕ(Справочник.Абонементы.ПустаяСсылка)) КАК Абонемент,
    ВЫБОР
        КОГДА Контрагенты.ДатаРожденияКлиента <> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
            ТОГДА РАЗНОСТЬДАТ(Контрагенты.ДатаРожденияКлиента, &ТекущаяДата, ГОД)
        ИНАЧЕ 0
    КОНЕЦ КАК Возраст,
    РАЗНОСТЬДАТ(&ТекущаяДата, ЕСТЬNULL(АктуальныеДоговораКлиентов.ДатаОкончанияСрокаДействия, &ТекущаяДата), ДЕНЬ) КАК ОсталосьДней,
    ВЫБОР
        КОГДА 1 В
                (ВЫБРАТЬ ПЕРВЫЕ 1
                    1
                ИЗ
                    РегистрСведений.СтатусыКонтрагентов.СрезПоследних(&ТекущаяДата) КАК СтатусыКонтрагентовСрезПоследних
                ГДЕ
                    СтатусыКонтрагентовСрезПоследних.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКонтрагентов.Потенциальный)
                    И Контрагенты.Ссылка = СтатусыКонтрагентовСрезПоследних.Контрагент)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК Потенциальный,
    ЕСТЬNULL(АктуальныеДоговораКлиентов.Номенклатура, ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)) КАК АбонементНоменклатура,
    Контрагенты.ДатаРегистрации КАК ДатаРегистрации,
    Версии.ДатаВерсии КАК ДатаИзменения,
    АктуальныеДоговораКлиентов.ДатаПриобретения КАК ДатаПриобретения,
    АктуальныеДоговораКлиентов.Продление КАК КоличествоАбонементов
ИЗ
    Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            а_ВерсииОбъектов.Объект КАК Объект,
            МАКСИМУМ(а_ВерсииОбъектов.ДатаВерсии) КАК ДатаВерсии
        ИЗ
            РегистрСведений.а_ВерсииОбъектов КАК а_ВерсииОбъектов
        
        СГРУППИРОВАТЬ ПО
            а_ВерсииОбъектов.Объект) КАК Версии
        ПО Контрагенты.Ссылка = Версии.Объект
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.а_АктуальныеАбонементыКлиентов КАК АктуальныеДоговораКлиентов
        ПО Контрагенты.Ссылка = АктуальныеДоговораКлиентов.Контрагент
ГДЕ
    НЕ Контрагенты.ЭтоГруппа
{ГДЕ
    (Контрагенты.Наименование ПОДОБНО &РасширенныйПоиск
            ИЛИ Контрагенты.Телефон ПОДОБНО &РасширенныйПоиск) КАК Поле2,
    (Контрагенты.Менеджер = &Менеджер) КАК Поле4,
    (Контрагенты.ДатаРожденияКлиента <= &ОтборВозрастОт) КАК Поле6,
    (Контрагенты.ДатаРожденияКлиента >= &ОтборВозрастДо) КАК Поле8,
    (НЕ &ОтборПоПотенциальным
            ИЛИ ВЫБОР
                КОГДА 1 В
                        (ВЫБРАТЬ ПЕРВЫЕ 1
                            1
                        ИЗ
                            РегистрСведений.СтатусыКонтрагентов.СрезПоследних(&ТекущаяДата) КАК СтатусыКонтрагентовСрезПоследних
                        ГДЕ
                            СтатусыКонтрагентовСрезПоследних.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКонтрагентов.Потенциальный)
                            И Контрагенты.Ссылка = СтатусыКонтрагентовСрезПоследних.Контрагент)
                    ТОГДА ИСТИНА
                ИНАЧЕ ЛОЖЬ
            КОНЕЦ) КАК Поле10,
    (НЕ &ОтборИменинники
            ИЛИ ДЕНЬ(Контрагенты.ДатаРожденияКлиента) = ДЕНЬ(&ТекущаяДата)
                И МЕСЯЦ(Контрагенты.ДатаРожденияКлиента) = МЕСЯЦ(&ТекущаяДата)) КАК Поле12,
    (НЕ &ОтборИзмененные
            ИЛИ Версии.ДатаВерсии > ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -3)) КАК Поле14,
    (НЕ &БезМенеджера
            ИЛИ Контрагенты.Менеджер = ЗНАЧЕНИЕ(Справочник.Сотрудники.ПустаяСсылка)) КАК Поле16}
12 MistaEr
 
07.08.17
13:05
Мне нужно получить только одно поле Булево из этого регистра сведений. Что в список, что для отбора
13 MistaEr
 
07.08.17
13:12
Вот отсюда я "научился" так писать): http://catalog.mista.ru/public/382500/
14 MistaEr
 
07.08.17
13:15
Хотя, там же написано ниже) Правильнее будет (2)
15 тарам пам пам
 
07.08.17
14:28
Срез последних разворачивается во вложенный запрос, и похоже оптимизатор постгри его уже не переваривает.

Поэтому можно попробовать включить итоги по срезу последних для регистра СтатусыКонтрагентов + убери дату из параметров вирт таблицы (в регистр же будущие данные вносить не будут?)
16 Dmitrii
 
гуру
07.08.17
14:40
Не умеет Postgres адекватно работать с таблицами среза последних регистра сведений. Факт признанный самими разработчиками из PostgresPro.

Поэтому необходимо (одно из двух):
либо заменить срез на первичную таблицу регистра
либо делать выбору из таблица среза последних во временную таблицу и делать соединение основной таблицы уже с этой временной.

Также возможно подойдёт способ из (15). Но только если данные берутся из таблицы среза без указаний параметра &Период (актуальные итоги, хранящиеся в физической таблице при условии включения итогов на регистре сведений). Но это надо проверять.
17 Вафель
 
07.08.17
14:52
если срез нужен на текущую дату, то разумно включить итоги по регистру
18 MistaEr
 
07.08.17
15:30
(15) Итоги срез последних у меня стоит. Но вот дату из параметров не убрал
19 MistaEr
 
07.08.17
15:32
(16) этот вариант тоже попробую
20 MistaEr
 
07.08.17
15:32
(17) Включены
21 Провинциальный 1сник
 
07.08.17
15:41
Попробуй
enable_nsetloop=off
22 lodger
 
07.08.17
15:54
(11) не люблю вложенные запросы. все равно их неявно выполнит. лучше соединение левое сделай с вирт таблицей (в ней параметры дата и статус наложить), потом анализировать на ЕСТЬ NULL.
23 H A D G E H O G s
 
07.08.17
15:57
Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
            аВерсииОбъектов.Объект КАК Объект,
            МАКСИМУМ(а
ВерсииОбъектов.ДатаВерсии) КАК ДатаВерсии
        ИЗ
            РегистрСведений.аВерсииОбъектов КАК аВерсииОбъектов
        
        СГРУППИРОВАТЬ ПО
            а_ВерсииОбъектов.Объект) КАК Версии

Это вы круто придумали, дааа
24 lodger
 
07.08.17
16:31
лучше убедите своего главного Юзера, что эта инфа в динамике набуй не нужна. достаточно предоставить отчет для мониторинга раз в неделю\месяц\пятилетку.
25 MistaEr
 
08.08.17
11:31
(23) А как можно исправить?
26 MistaEr
 
08.08.17
11:34
(22) Эти параметры нельзя на вирт таблицу накладывать. Про дату написали в (15) а если статус положить он выведет последнюю дату когда был такой статус а не статус на последнюю дату
AdBlock убивает бесплатный контент. 1Сергей