2010-08-04 6 views
10

Sto creando un'app Web con alcune complesse associazioni sottostanti. Per risolvere diversi problemi che stavo facendo ho creato una vista UNION. Probabilmente ci sono molti altri modi in cui questo potrebbe essere risolto.Le VISIONI PostgreSQL sono state create di recente ogni volta che vengono interrogate?

Ma ora sto considerando l'efficienza del mio progetto e volevo sapere se una VIEW è stata appena creata ogni volta che viene interrogata, oppure viene creata una sola volta e mantenuta aggiornata.

Per elaborare, se ho table_a (100 record) e table_b (100 record) e faccio una vista UNION, quindi ho creato una vista con 200 record.

L'intero processo si verifica ogni volta che eseguo una selezione rispetto alla vista?

Ancora una volta, ovviamente, ogni volta che aggiorno la tabella sottostante, la vista viene aggiornata, ma la vista aggiorna questo record o ricrea l'intera vista da zero?

Dale

+0

Btw, un 'INSERTO' può riguardare solo una tabella alla volta, quindi se la tua vista fa 'UNISCI' su più tabelle, il tuo 'INSERTO' può solo elencare le colonne da una delle tabelle. – JohnB

risposta

12

Un punto di vista non è altro che una query con un nome. Ci sono possibili ottimizzazioni relative ai perf, che alcuni DBMS realizzano meglio di altri (pgSQL sembra essere dalla parte migliore), come riutilizzare il piano di query, il controllo dell'accesso memorizzato nella cache ecc.

Tuttavia, alla fine della giornata, quasi sempre, puoi aspettarti che una vista si comporti come l'emissione diretta dell'SQL. Con la differenza che è possibile concedere l'accesso a questa query senza concedere l'accesso alle tabelle sottostanti.

Ci sono ottimizzazioni che si possono fare che cambiano il comportamento (rendendole simili a una tabella) e che potrebbero o non potrebbero esistere in pgSQL come viste materializzate (non mi dispiace idea su pgSQL), ma questo è solo il pignolo.

3

L'intero processo si verifica ogni volta che eseguo una selezione rispetto alla vista?

Sì.
Una vista non materializzata (PostgreSQL non supporta le viste materializzate) è solo un'istruzione SQL preparata: otterresti le stesse prestazioni sostituendo un riferimento di visualizzazione con una sottoquery contenente la SELECT su cui si basa la vista.

Ecco perché i valori basati sulle tabelle di supporto vengono visualizzati ogni volta che si esegue una query sulla vista, non sono chiaro se le manipolazioni delle colonne sono rese visibili in PostgreSQL senza aggiornare la vista. su SELECT * FROM table_x, quindi aggiungi o elimina una colonna da table_x - la maggior parte dei database richiederà di aggiornare la vista per vedere quella modifica tramite la vista.

Le viste degli edifici in cima alle viste dovrebbero essere scoraggiate: sono fragili; non lo saprai fino a quando non eseguirai una vista dipendente da un'altra se c'è un problema. E non c'è alcun guadagno in termini di prestazioni, piuttosto il contrario. Il riutilizzo del codice non funziona bene in un ambiente basato su SET ...

+6

postgres supporta visioni materializzate dal 9.3 http://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html –

3

Utilizzare ESPLORA per vedere come viene eseguita una VISTA, vedrai gli stessi risultati di una query normale.

EXPLAIN 
SELECT * FROM name_of_your_view WHERE foo = 23; 

PostgreSQL cercherà di ottimizzare la query interna, anche quando si partecipa a vista, hanno una vista utilizzando altre viste, ecc Cercate di evitare situazioni in cui un punto di vista è da eseguire prima l'ottimizzatore può fare è (ottimo) lavoro. Aggregati, ORDER BY e LIMIT sono esempi di potenziali problemi quando si utilizzano viste nidificate interne. Basta usare EXPLAIN per vedere cosa sta succedendo.

+0

Grazie Frank. Cercando di utilizzare il metodo EXPLAIN ma non ricevo nulla di ragionevole in risposta. Ora capisco che una vista è in realtà solo una dichiarazione di interrogazione. Quello che voglio sapere ora è, - se faccio una selezione contro la vista, la query prima cerca tutte le righe per creare la vista, e poi guarda attraverso tutte le righe per effettuare la selezione? O è più efficiente di questo? – Oscar

+0

Questa è la query EXPLAIN che ho fatto: EXPLAIN SELECT * FROM person_roles WHERE person_id = 3; E questo è il risultato: Sort (costo = 2.95..2.97 righe = 9 width = 42) Sort chiave: public.links.created_at -> HashAggregate (costo = 2.71..2.80 righe = 9 width = 42) -> Aggiungi (costo = 0.00..2.46 righe = 9 larghezza = 42) -> Seq Scansione sui collegamenti (costo = 0.00..19 righe = 5 larghezza = 42) Filtro: (origine_id = 3) -> Seq Scansione sui collegamenti (costo = 0,00..19 righe = 4 larghezza = 42) Filtro: (rcvd_id = 3) – Oscar

+0

PostgreSQL è molto intelligente, non preoccuparti. L'ottimizzatore controlla le statistiche che ha sulle tabelle della query, controlla gli indici disponibili e le istruzioni WHERE. L'ottimizzatore riscrive la tua query e quindi è magico scoprire quale queryplan sarebbe il più veloce. Nel tuo caso usa scansioni sequenziali e non usa alcun indice. Immagino che la quantità di dati sia molto limitata, ma potrebbe anche darsi che non si abbiano indici sulle colonne origin_id e rcvd_id. Controlla http://www.postgresql.org/docs/current/interactive/planner-stats-details.html per leggere come funzionano le cose. –

Problemi correlati