172 похожих чатов

Есть ли очевидный способ оптимизировать скорость выполнения такого запроса? CREATE OR

REPLACE VIEW agency.task_fact AS (
SELECT
*,
atomic_gross_profit / atomic_expense AS atomic_roi
FROM (
SELECT
*,
atomic_income - atomic_expense AS atomic_gross_profit
FROM (
SELECT
id,

atomic_hour_rate_rub,
atomic_hour_price_rub,
atomic_duration_hours,
atomic_duration_hours * atomic_hour_rate_rub AS atomic_expense,
atomic_duration_hours * atomic_hour_price_rub AS atomic_income,

Полностью:
https://gist.github.com/GreenRobot777/e37457f5a72f033cb9575b272aa456e2

13 ответов

8 просмотров

По-моему, использование ORDER BY в view — это грубая ошибка, потому что это на самом деле не гарантирует ничего, кроме тормозов. А в остальном — как обычно: https://t.me/pgsql/288632

Александр-Март 🌍 Автор вопроса

Скорость пофиксил тем, что перешёл на MATERIALIZED VIEW.

Александр-Март 🌍 Автор вопроса

Тут вычисления используют результаты предыдущих вычислений, для этого используются вложенные SELECTы. Есть ли разница между тем, чтобы делать вложенные селекты и явно показывать, что посчитанные значения можно переиспользовать или можно писать всё в одном селекте (делать одни и те же умножения несколько раз) и оптимизатор сам поймёт, что их можно переиспользовать? Где можно про это прочитать в доке?

Александр Март 🌍
Тут вычисления используют результаты предыдущих вы...

а нельзя там эти данные генерировать на триггерах сразу в нужной форме?

Александр Март 🌍
Скорость пофиксил тем, что перешёл на MATERIALIZED...

А почему Вы ничего другого показывать / пробовать не стали? И Вы понимаете, что запрос и mat.view — совсем не одно и то же?

Александр Март 🌍
Тут вычисления используют результаты предыдущих вы...

Типа вот такого, только тут порядок столбцов обратный, уж извините CREATE OR REPLACE VIEW agency.task_fact AS ( select t.id, t.name, min(tie.started_at) as started_at, max(tie.ended_at) as ended_at, sum(tie.duration_hours) as atomic_duration_hours, sum(tie.duration_hours) * con.hour_rate_rub AS atomic_expense, sum(tie.duration_hours) * sum(d.hour_price_rub) AS atomic_income, con.hour_rate_rub as atomic_hour_rate_rub, sum(d.hour_price_rub) as atomic_hour_price_rub, t.user_story__id, fe.id as feature__id, ep.id as epic__id, prj.id as project__id, prg.id as program__id, t.contract__id, t.payout__id, cr.id as contractor__id, te.id as team__id, tel.id as team_lead__id, crl.id as contractor_level__id, t.release__id, pr.id as product__id, prc.id as product_class__id, ((sum(tie.duration_hours) * sum(d.hour_price_rub)) - (sum(tie.duration_hours) * con.hour_rate_rub)) / (sum(tie.duration_hours) * con.hour_rate_rub) as atomic_roi, (sum(tie.duration_hours) * sum(d.hour_price_rub)) - (sum(tie.duration_hours) * con.hour_rate_rub) as atomic_gross_profit from agency.task t left join agency.release r on r.id = t.release__id left join agency.product pr on pr.id = r.product__id left join agency.product_class prc on prc.id = pr.product_class__id left join agency.contract con on con.id = t.contract__id left join agency.contractor cr on cr.id = con.contractor__id left join agency.contractor_level crl on crl.id = cr.contractor_level__id left join agency.team te on te.id = con.team__id left join agency.team_lead tel on tel.id = te.team_lead__id left join agency.user_story us on us.id = t.user_story__id left join agency.feature fe on fe.id = us.feature__id left join agency.epic ep on ep.id = fe.epic__id left join agency.project pr on prj on prj.id = ep.project__id left join agency.program prg on prg.id = prg.program__id left join agency.task__deal td on td.task__id = t.id left join agency.deal d on d.id = td.deal__id left join agency.time_entry tie on tie.task__id = t.id group by t.id, t.name, con.hour_rate_rub, t.user_story__id, fe.id, ep.id, prj.id, prg.id, t.contract__id, t.payout__id, cr.id, te.id, tel.id, crl.id, t.release__id, pr.id, prc.id );

Александр Март 🌍
Тут вычисления используют результаты предыдущих вы...

А что Вы имеете в виду, конкретно? Что-то вроде SELECT (a+b)*(a-b) FROM (SELECT c*d AS a, e*f AS b FROM ...) AS t1 против SELECT (c*d+e*f)*(c*d-e*f) FROM ...?

Александр-Март 🌍 Автор вопроса
Iurii Shaporenko
Я бы переписал на один select с кучей left join'ов

А по вычислениям это будет реально дешевле? Или только для удобства восприятия?

Александр Март 🌍
А по вычислениям это будет реально дешевле? Или то...

Дешевле чем что? Мне кажется, или Вы до сих пор не задали конкретного вопроса, а на уточняющие не ответили? ;) Или я пропустил?

Александр Март 🌍
А по вычислениям это будет реально дешевле? Или то...

В принципе, без знания таблиц и их содержимого сложно так навскидку сказать, но то, что у вас в текущей реализации вьюхи к одной и той же таблице по 4-5 раз обращения в подзапросах происходят, как мне кажется, с переходом на left join'ы быстродействие должно увеличиться

Александр-Март 🌍 Автор вопроса
Yaroslav Schekin
А что Вы имеете в виду, конкретно? Что-то вроде S...

Да, есть ли разница по стоимости вычисления или оптимизатор в данном случае увидит дублирующиеся вычисления и выполнит умножение один раз? Буду благодарен, если ткнёте в раздел документации, где об этом пишут или подскажете, куда копать.

Александр Март 🌍
Да, есть ли разница по стоимости вычисления или оп...

Нет, планировщик не ищет дубли вычислений (не считая GROUP BY, где это необходимо по смыслу). Не помню, чтобы об этом было написано в документации — это несущественная деталь реализации.

Похожие вопросы

Обсуждают сегодня

а через ESC-код ?
Alexey Kulakov
29
30500 за редактор? )
Владимир
47
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
13
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Как передать управляющий символ в открытую через CreateProcess консоль? Собсна, есть процедура: procedure TRedirectThread.WriteData(Data: OEMString); var Written: Cardinal;...
Serjone
6
в JclConsole объявлено так: function CtrlHandler(CtrlType: DWORD): BOOL; stdcall; - где ваше объявление с stdcall? у вас на картинке нет stdcall
Karagy
8
Ребят в СИ можно реализовать ООП?
Николай
33
program test; {$mode delphi} procedure proc(v: int32); overload; begin end; procedure proc(v: int64); overload; begin end; var x: uint64; begin proc(x); end. Уж не знаю...
notme
6
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта