|
построение cte - резкие тормоза при расширении количества cte в with
|
|||
---|---|---|---|
#18+
Всем привет, не подскажите в чем может быть принципиальная ошибка в построении/использовании cte для pg16/17 в двух словах - вывожу информацию по нескольким типам объектов и их атрибутам - к атрибутам многократное обращение - к объектам просто три одноразовых выборки через left join если по отдельности вызывать cte - то более менее - медленно конечно, но... если в комбинации через left join более 2x запросов = резкие на порядок тормоза не могу понять в чем дело - какая то принципиальная ошибка в моем подходе.... вот запрос with _value_attr as NOT MATERIALIZED( select av.Object_id as id, av.Attrib_ID as IdTypeAttr, coalesce(sv.value,'')||coalesce(sv.value1,'') as sValue, nv.value as nValue, dv.value as dValue from LSDBO.attrib_value as av left join LSDBO.value_string as sv on sv.id=av.Value_ID left join LSDBO.value_datetime as dv on dv.id=av.Value_ID left join LSDBO.value_numeric as nv on nv.id=av.Value_id where av.Attrib_ID in( 3000000000105,100004086600000,3000000000106,100037488300000,3000000000122, 100000019000005,100000648000000,3000000000101,100005428000000, 100004087100000, -33,100004081200000 ) ), _obj as NOT MATERIALIZED( Select rw.id, rw.cd, tw.mnemo, rw.description From LSDBO.object_reference AS rw left join LSDBO.object_type AS tw ON rw.type_id = tw.id Where tw.mnemo in ('Req','tnd','PSft', 'PHrd', 'PExp', 'PSrv', 'pPls','Del') -- order by rw.id ), _del as NOT MATERIALIZED( Select --выборка по заказам по дате закрытия vv1.sValue as d_Account, vv2.dValue AS d_dAccount, rw.id AS d_ID, vv0.sValue AS d_Status, vv4.sValue AS d_Currency, --(select LSDBO.Ric_Get_ShortFIO(vv5.sValue)) as Del_Manager, vv5.sValue as d_Manager, Case abs(vv7.nValue) when 10 then 'Клиент' when 20 then 'Дилер' when 30 then 'Клиент дилера' when 40 then 'Частное лицо' else '...' end AS d_Channel--, -- vv15.nValue as dRequestId From _obj as rw left join _value_attr AS vv0 ON vv0.id= rw.id and vv0.idTypeAttr= 3000000000105 left join _value_attr AS vv1 ON vv1.id= rw.id and vv1.idTypeAttr= 100004086600000 left join _value_attr AS vv2 ON vv2.id= rw.id and vv2.idTypeAttr= 3000000000106 left join _value_attr AS vv4 ON vv4.id= rw.id and vv4.idTypeAttr= 100037488300000 left join _value_attr AS vv5 ON vv5.id= rw.id and vv5.idTypeAttr= 3000000000122 left join _value_attr AS vv7 ON vv7.id= rw.id and vv7.idTypeAttr= 100000019000005 Where rw.mnemo='Del' and vv0.sValue in ('Исполнена','Оплата | Отгрузка') --not in ("Аннулирована", "Заказ", "Предложение") and vv2.dValue between p_dbegin and p_dend -- order by rw.id ), _req as NOT MATERIALIZED( Select rw.id as req_id, vv2.svalue AS R_Author, vv1.nvalue as req_del_id From _obj as rw left join _value_attr AS vv2 ON vv2.id= rw.id and vv2.idTypeAttr= -33 left join _value_attr AS vv1 ON vv1.id= rw.id and vv1.idTypeAttr=100004081200000 Where rw.mnemo in ('Req','tnd') -- and vv1.nvalue>0 and vv1.nvalue in (select d_ID from _del) --order by vv1.nvalue ), _prod as NOT MATERIALIZED( Select -- rw.Mnemo, Case rw.Mnemo when 'PSft' then 'Программное обеспечение' when 'PHrd' then 'Оборудование' when 'PExp' then 'Прочие продукты' when 'PSrv' then 'Услуги' when 'pPls' then 'Обучение' else '...' end as prod_Mnemo, vv1.nValue as prod_del_id, --дополнение позициями спецификации vv3.svalue as prod_PriceName, coalesce(vv16.nvalue,0) as prod_dPrice, vv6.svalue AS prod_Currency, vv7.svalue AS prod_Xml from _obj as rw left join _value_attr AS vv1 ON vv1.id= rw.id and vv1.idTypeAttr= 100000648000000 left join _value_attr AS vv3 ON vv3.id= rw.id and vv3.idTypeAttr= 3000000000101 left join _value_attr AS vv6 ON vv6.id= rw.id and vv6.idTypeAttr= 100005428000000 left join _value_attr AS vv7 ON vv7.id= rw.id and vv7.idTypeAttr= 100037488300000 left join _value_attr AS vv16 ON vv16.id= rw.id and vv16.idTypeAttr= 100004087100000 Where rw.mnemo in ('PSft', 'PHrd', 'PExp', 'PSrv', 'pPls') and vv1.nValue in (select d_IDfrom _del) --order by vv1.nValue ), _res as NOT MATERIALIZED( select * from _del as d left join _req as r on d.d_ID=r.req_del_id left join _prod as p on p.prod_del_id=d.d_ID --select * from _del as d, _req as r, _prod as p ) select (select LSDBO.Ric_Get_ShortFIO(D_Manager))::text as Del_Manager, Del_Account::text, Del_dAccount::timestamp without time zone, Del_Status::text, Del_Currency::text, Del_Channel::text, prod_Xml::text as pXml, prod_Mnemo::text as pMnemo, prod_PriceName::text as pPriceName, prod_dPrice::double precision as pdPrice, prod_Currency::text as pCurrency, (select LSDBO.Ric_Get_ShortFIO(R_Author))::text AS Req_Author, (select LSDBO.Ric_Get_OccurrenceSource(req_id))::text as Req_ist_CRM, (select fTrend from lsdbo.Ric_Get_attrUsers(100004487800000) where fFIO =R_Author)::text AS Req_Author_Trend from _res; -- LIMIT 10; первый cte (многократное чтение) = _value запрос значений атрибутов (строки, числа, данные) (через in таблицы подрезаны покороче) (~9 577 290 записей) второй cte = _obj запрос значений типов объектов (также через in подрезано количество)(465 948 записей) третий cte = _del = основной запрос (по основному типу объекта) ~289 записей четвертый и пятый cte = _req и _prod вспомогательная инфа к _del = в итоге ~516 записей проблема отдельные запросы из cte select * from _del - выполняется ~быстро (среднее 2.6 сек) 289 строк select * from _prod - выполняется ~быстро (среднее 29 сек) 516 строк select * from _req - выполняется ~быстро (среднее 25 сек) 289 строк но стоит добавить связь одну связь ... and vv1.nValue in (select d_IDfrom _del) или select * from _del as d left join _prod as p on p.prod_del_id=d.d_ID select * from _del as d left join _req as r on d.d_ID=r.req_del_id запрос выполняется уже 10 минут а если добавить все три select * from _del as d left join _req as r on d.d_ID=r.req_del_id left join _prod as p on p.prod_del_id=d.d_ID то более 30 минут пробовал разные варианты - в составе cte (с материализацией и без) и без него - принципиально разница не большая off в mssql (mssql из коробки, железо серверное) на тех же конструкциях на аналогичной базе (в произвольных вариантах) все летает анализ планов на https://explain.tensor.ru/ выдает рекомендации по добавлению своих индексов к таблицам выборки (структура данных не моя - менять принципиально не можем) postgresql 16/17 с настройками из коробки в среднем 317~420 транзакций в секунду железо - чуть круче офисной тачки гдето простой затык в построении запроса - уже неделю только не могу понять где)))) решил спросить здесь ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2025, 11:04 |
|
построение cte - резкие тормоза при расширении количества cte в with
|
|||
---|---|---|---|
#18+
Тяпа-ляпа [игнорируется] типа изобразить табличную переменную mssql - в виде временной таблицы сеанса postgresql в запросе типа 'plpgsql'... создав заполнив и убив ее ? ... думал эту таблицу с атрибутами в массив засунуть и работать с массивами - но тоже вроде не то, думал в виде отдельной udf оформить или таблицу свою создать постоянную обобщенную с индексами (но ее нужно поддерживать... а это уже очень глубоко) (проблема в том что в каждом отдельном запросе я использую свой набор атрибутов (id для выборки) - и не ясно что быстрее - читать инфу напрямую из базы или через промежуточную выборку) ... с материализацией тож запутался (думал просто ядро наше с mssql на postgresql переписать и забыть... но не тут то было) ... ок попробую спасибо за идею! напишу тогда по результатам ... |
|||
:
Нравится:
Не нравится:
|
|||
10.03.2025, 13:11 |
|
|
start [/forum/topic.php?fid=53&tid=2187215]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
58ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
37ms |
get tp. blocked users: |
1ms |
others: | 20ms |
total: | 154ms |
0 / 0 |