Yiha!
Wir konnten den Fehler festmachen:
Die Performance geht nicht in den Keller, wenn man obige Funktion einmalig ausführt.
Sie führt nur dann zu Problemen, wenn unsere Kunden mit mehreren Rechnern die Funktion parrallel ausführen.
Dies möchte ich nun so abändern:
Wenn die Funktion aufgerufen wird, wird in einer Orga-Tabelle eine Spalte nach einem Wert abgefragt.
Wenn dieser '1' ist, wird die Funktion verlassen.
Wenn er != '1' ist, wird er mit '1' belegt und die Funktion wird ausgeführt. Am Ende wird sie dann wieder auf '0' gesetzt.
Dabei muss das abändern auf '1' sofort geschehen (commit), damit andere Abfragen die Änderung direkt wahrnehmen.
Soweit bin ich jetzt:
Code:
CREATE OR REPLACE FUNCTION "public"."mv_refresh" (
"matview" varchar
)
RETURNS "pg_catalog"."void" AS
$body$
DECLARE
matview ALIAS FOR $1;
entry t_matviews%ROWTYPE;
dtnow TIMESTAMP;
dtlater TIMESTAMP;
scalculating varchar(1);
BEGIN
SELECT timeofday() INTO dtnow;
SELECT * INTO entry FROM t_matviews WHERE mv_name = matview;
IF NOT FOUND THEN
RAISE EXCEPTION 'Materialized view % does not exist.', matview;
END IF;
-- Hier die Abfrage, ob nicht bereits die Statistik aktualisiert wird.
SELECT scalculating from t_matviews WHERE mv_name = matview INTO scalculating;
IF scalculating = '1' THEN
RETURN;
--ELSE
-- UPDATE t_matviews SET scalculating='1' WHERE mv_name=matview ;
END IF ;
EXECUTE 'DELETE FROM ' || matview;
EXECUTE 'INSERT INTO ' || matview
|| ' SELECT * FROM ' || entry.v_name;
SELECT timeofday() INTO dtlater;
UPDATE t_matviews SET last_refresh=dtlater, idauer=(dtlater - dtnow) WHERE mv_name=matview;
RETURN;
END
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY DEFINER;
1.: Sobald ich die Zeile ELSE / UPDATE t_matviews SET scalculating='1'... einkommentiere, erhalte ich folgenden Fehler:
Code:
FEHLER: Fehler »Syntaxfehler« bei »$1«
LINE 1: UPDATE t_matviews SET $1 ='1' WHERE mv_name= $2
^
QUERY: UPDATE t_matviews SET $1 ='1' WHERE mv_name= $2
CONTEXT: SQL statement in PL/PgSQL function "mv_refresh" near line 22 2.: Damit ich bei parallelen Abfragen sofort den Status erkenne, müsste die Zeile
"UPDATE t_matviews SET scalculating='1' WHERE mv_name=matview ;"
mit einem Beginn; eingeleitet und mit einem comitt; abgeschlossen werden?
Lesezeichen