1

Ich arbeite an Read-Replica der PostgreSQL-Datenbank ohne die Möglichkeit, temporäre Tabellen (schreibgeschützte Transaktion) zu erstellen.Wiederverwendung der gespeicherten Prozedur führt zu PostgreSQL

Ich habe gespeichert Prozedur foo(...), die mich zurückgibt TABLE(...) Ergebnis (oder SETOF Foo_Type das ist das gleiche).

Diese Foo_Type hat einige type Feld, die Art der Daten in der Zeile definiert.

In einem anderen Verfahren foo_wrapper(...) mit festen Rückgabetyp (es ist auch TABLE(...) oder der SETOF Foo_Wrapper_Type sagen wir mal) ich folgendes tun müssen:

je nach Foo_Type.type Wert I Ergebnisse müssen mit left join von foo(...) mit verschiedenen Tabellen verschmelzen. Dies ist, wie es im Moment getan wird:

... 
return query 
select 
    ft.*, 
    a1.x1 
    from foo(param1, param2, ...) ft 
    left join a_table a on ... 
    where ft.type = 'value_1' 

union 
select 
    ft.*, 
    b1.x1 
    from foo(param1, param2, ...) ft 
    left join b_table b on ... 
    where ft.type = 'value_2' 

... 

Es gibt Dutzende dieses union es.

Erzähl mir nicht wie böse und schrecklich mein Schema ist. Ich weiß es, es ist ein Legacy-Schema.

Was ich frage über ist, wie zu vermeiden, mehrere Anrufe von foo(...) Verfahren in dieser Aussage?

Diese foo_wrapper(...) Prozedur arbeitet extrem langsam. Ich vermute, dass es wegen mehrerer Aufrufe von foo(...) Prozedur mit denselben Parametern ist, und ich bin nicht sicher, ob DB seine Ergebnisse in einer Sitzung zwischenspeichert.

So besteht meine Frage aus 2 Teilen:

  1. Ist eine Möglichkeit, zu "extrahieren" und die Ergebnisse der foo(...) vor meiner großen union-select zu retten? DECLARE results SETOF Foo_Type funktioniert nicht.

  2. Vielleicht ist es nicht der Punkt für die Optimierung und jemand kann sicher behaupten, dass die Ergebnisse des ersten Anrufs von foo(...) für weitere Aufrufe in diesem Verfahren zwischengespeichert werden?

Antwort

2

eine gemeinsame Tabellenausdruck Verwendung:

return query 
with foo_data as (
    select * 
    from foo(param1, param2, ...) 
) 
select ft.*, 
     a1.x1 
from foo_data ft 
    left join a_table a on ... 
where ft.type = 'value_1' 
union 
select ft.*, 
     b1.x1 
from foo_data ft 
    left join b_table b on ... 
where ft.type = 'value_2' 
... 

Sie wollen wahrscheinlich union all statt union verwenden.

+0

WOW, sieht wie eine Entscheidung aus. Ich werde es morgen überprüfen und meine Abstimmung und Überprüfung wird nicht verzögert werden! Vielen Dank! – Andremoniy

+0

Das ist toll, funktioniert wie ein Zauber. Vielen Dank – Andremoniy

Verwandte Themen