|
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) а если статус положить он выведет последнюю дату когда был такой статус а не статус на последнюю дату
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |