2016-01-01 15 views
7

La mia applicazione richiede molto database, quindi sto provando a ridurre il carico sul database. Sto usando PostgreSQL come rdbms e python è il linguaggio di programmazione. Per ridurre il carico sto già utilizzando un meccanismo di memorizzazione nella cache nell'applicazione. Il tipo di cache che ho usato è una cache del server, cache del browser. Attualmente sto ottimizzando la cache delle query di PostgreSQL per farlo in linea con le caratteristiche delle query eseguite sul server.Abilitare la cache di query in postgreSQL per migliorare le prestazioni

Domande:

  1. E 'possibile multa cache delle query sintonizzarsi a livello di singolo database?
  2. È possibile ottimizzare la cache delle query su una base per tabella?
  3. si prega di fornire tutorial per imparare la cache di query in PostgreSQL.
+1

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

risposta

-1

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);