Ho sviluppato un sistema per i risultati di memorizzazione nella cache, per velocizzare i risultati richiesti da una soluzione basata sul Web. Ho riprodotto di seguito essenzialmente ciò che ha fatto:
Di seguito sono riportate le tabelle e le funzioni di gestione della cache generica.
CREATE TABLE cached_results_headers (
cache_id serial NOT NULL PRIMARY KEY,
date timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_access timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
relid regclass NOT NULL,
query text NOT NULL,
rows int NOT NULL DEFAULT 0
);
CREATE INDEX ON cached_results_headers (relid, md5(query));
CREATE TABLE cached_results (
cache_id int NOT NULL,
row_no int NOT NULL
);
CREATE OR REPLACE FUNCTION f_get_cached_results_header (p_cache_table text, p_source_relation regclass, p_query text, p_max_lifetime interval, p_clear_old_data interval) RETURNS cached_results_headers AS $BODY$
DECLARE
_cache_id int;
_rows int;
BEGIN
IF p_clear_old_data IS NOT NULL THEN
DELETE FROM cached_results_headers WHERE date < CURRENT_TIMESTAMP - p_clear_old_data;
END IF;
_cache_id := cache_id FROM cached_results_headers WHERE relid = p_source_relation AND md5(query) = md5(p_query) AND query = p_query AND date > CURRENT_TIMESTAMP - p_max_lifetime;
IF _cache_id IS NULL THEN
INSERT INTO cached_results_headers (relid, query) VALUES (p_source_relation, p_query) RETURNING cache_id INTO _cache_id;
EXECUTE $$ INSERT INTO $$||p_cache_table||$$ SELECT $1, row_number() OVER(), r.r FROM ($$||p_query||$$) r $$ USING _cache_id;
GET DIAGNOSTICS _rows = ROW_COUNT;
UPDATE cached_results_headers SET rows = _rows WHERE cache_id = _cache_id;
ELSE
UPDATE cached_results_headers SET last_access = CURRENT_TIMESTAMP;
END IF;
RETURN (SELECT h FROM cached_results_headers h WHERE cache_id = _cache_id);
END;
$BODY$ LANGUAGE PLPGSQL SECURITY DEFINER;
Il seguente è un esempio di come utilizzare le tabelle e funzioni sopra, per una data vista denominata my_view
con un campo key
essere selezionata entro un intervallo di valori interi. Sostituirai tutto quanto segue con le tue esigenze particolari e sostituirai my_view
con una tabella, una vista o una funzione. Sostituire anche i parametri di filtraggio come richiesto.
CREATE VIEW my_view AS SELECT ...; -- create a query with your data, with one of the integer columns in the result as "key" to filter by
CREATE TABLE cached_results_my_view (
row my_view NOT NULL,
PRIMARY KEY (cache_id, row_no),
FOREIGN KEY (cache_id) REFERENCES cached_results_headers ON DELETE CASCADE
) INHERITS (cached_results);
CREATE OR REPLACE FUNCTION f_get_my_view_cached_rows (p_filter1 int, p_filter2 int, p_row_from int, p_row_to int) RETURNS SETOF my_view AS $BODY$
DECLARE
_cache_id int;
BEGIN
_cache_id := cache_id
FROM f_get_cached_results_header('cached_results_my_view', 'my_view'::regclass,
'SELECT r FROM my_view r WHERE key BETWEEN '||p_filter1::text||' AND '||p_filter2::text||' ORDER BY key',
'15 minutes'::interval, '1 day'::interval); -- cache for 15 minutes max since creation time; delete all cached data older than 1 day old
RETURN QUERY
SELECT (row).*
FROM cached_results_my_view
WHERE cache_id = _cache_id AND row_no BETWEEN p_row_from AND p_row_to
ORDER BY row_no;
END;
$BODY$ LANGUAGE PLPGSQL;
Esempio: recuperare righe da 1 a 2000 dai risultati my_view cache filtrati per key BETWEEN 30044 AND 10610679
. Esegui una prima volta e i risultati della query verranno memorizzati nella cache nella tabella cached_results_my_view
e verranno restituiti i primi 2000 record. Eseguirlo di nuovo poco dopo e i risultati verranno recuperati dalla tabella cached_results_my_view
direttamente senza eseguire la query.
SELECT * FROM f_get_my_view_cached_rows(30044, 10610679, 1, 2000);
Se stai cercando il tipo di modifica disponibile in Oracle, la risposta è: non è lì. Ma qui ci sono alcuni link che potresti voler leggere http://www.postgresql.org/docs/current/static/pgprewarm.html https://wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server https: //wiki.postgresql .org/wiki/Performance_Optimization – Jayadevan