2010-08-04 11 views
10

Estoy creando una aplicación web que tiene algunas asociaciones subyacentes complejas. Para resolver varios problemas que estaba teniendo, creé una vista de UNIÓN. Probablemente hay muchas otras formas en que esto podría ser resuelto.¿Se crean nuevas OPINIONES de PostgreSQL cada vez que se consultan?

Pero ahora estoy considerando la eficiencia de mi diseño, y quería saber si se crea una VISTA de nuevo cada vez que se consulta, o solo se crea una vez, y se mantiene actualizada.

Para elaborar, si tengo table_a (100 registros) y table_b (100 registros) y hago una vista UNION, entonces he creado una vista con 200 registros.

¿Todo este proceso ocurre cada vez que selecciono la Vista?

De nuevo, obviamente, cada vez que actualizo los registros de la tabla subyacente, la vista se actualiza, pero ¿la vista actualiza este registro o recrea la vista completa desde cero?

Dale

+0

Por cierto, un 'INSERT 'solo puede afectar una tabla a la vez, por lo que si su vista tiene' JOIN' en varias tablas, su 'INSERT' solo puede listar columnas de una de las tablas. – JohnB

Respuesta

12

Una vista no es más que una consulta con un nombre. Hay posibles optimizaciones relacionadas con perf, que algunos DBMS se dan cuenta mejor que otros (pgSQL parece ser mejor), como reutilizar el plan de consulta, control de acceso en caché, etc.

Sin embargo, al final de ese día, casi siempre, puede esperar que una vista se comporte como emitir el SQL directamente. Con la diferencia de que puede otorgar acceso a esta consulta sin otorgar acceso a las tablas subyacentes.

Hay optimizaciones que podría hacer que cambian el comportamiento (hacerlas como una media tabla) y que pueden o no existir en pgSQL como vistas materializadas (lo siento, no tengo idea de pgSQL), pero esto es solo una trampa.

3

¿Todo este proceso ocurre cada vez que selecciono la Vista?

Sí.
Una vista no materializada (PostgreSQL no admite vistas materializadas) es solo una declaración SQL preparada: obtendría el mismo rendimiento al reemplazar una referencia de vista por una subconsulta que contenga el SELECT en el que se basa la vista.

Es por eso que los valores basados ​​en las tablas secundarias aparecen cada vez que ejecuta una consulta en la vista, no estoy seguro si las manipulaciones de columna se hacen visibles en PostgreSQL sin actualizar la vista - IE: Si crea una vista basada en SELECT * FROM table_x, y luego agregue o elimine una columna de table_x - la mayoría de las bases de datos requerirán que actualice la vista para ver ese cambio a través de la vista.

Se debe desalentar la creación de vistas en la parte superior de las vistas; son frágiles; no sabrá hasta ejecutar una vista dependiente de otra si hay un problema. Y no hay ganancia de rendimiento, sino todo lo contrario. La reutilización de código no funciona bien en un entorno basado en SET ...

+6

postgres admite vistas materializadas desde 9.3 http://www.postgresql.org/docs/9.3/static/sql-creatematerializedview.html –

3

Use EXPLAIN para ver cómo se ejecuta una VISTA, verá los mismos resultados que una consulta normal.

EXPLAIN 
SELECT * FROM name_of_your_view WHERE foo = 23; 

PostgreSQL tratará de optimizar la consulta interna, aun cuando se une puntos de vista, tienen puntos de vista utilizando otros puntos de vista, etc. Trate de evitar situaciones en las que un punto de vista ha de ser ejecutado antes de que el optimizador puede hacer es (gran) trabajo. Los agregados, ORDER BY y LIMIT son ejemplos de problemas potenciales al usar vistas anidadas internas. Solo usa EXPLAIN para ver qué está pasando.

+0

Gracias Frank. Tratando de usar el método EXPLAIN pero no recibo nada sensato en respuesta. Ahora entiendo que una Vista es realmente solo una declaración de consulta. Lo que quiero saber ahora es: si hago una selección en contra de la vista, ¿la consulta busca primero todas las filas para crear la vista y luego mira a través de todas las filas para hacer la selección? ¿O es más eficiente que esto? – Oscar

+0

Esta es la consulta EXPLAIN que hice: EXPLAIN SELECCIONAR * FROM person_roles WHERE person_id = 3; Y este es el resultado: Ordenar (coste = 2.95..2.97 filas = anchura 9 = 42) Ordenar Clave: public.links.created_at -> HashAggregate (coste = 2.71..2.80 filas = 9 width = 42) -> Adjuntar (costo = 0.00..2.46 filas = 9 ancho = 42) -> Seq Escanear en enlaces (costo = 0.00..1.19 filas = 5 ancho = 42) Filtro: (origen_id = 3) -> Seq Escanear en enlaces (costo = 0.00..1.19 filas = 4 ancho = 42) Filtro: (rcvd_id = 3) – Oscar

+0

PostgreSQL es muy inteligente, no se preocupe. El optimizador comprueba las estadísticas que tiene sobre las tablas en su consulta, comprueba los índices disponibles y las sentencias WHERE. El optimizador reescribe su consulta y luego es mágico descubrir qué plan de consulta sería el más rápido. En su caso, utiliza escaneos secuenciales y no usa ningún índice. Supongo que la cantidad de datos es muy limitada, pero también podría ser que no tenga índices en las columnas origin_id y rcvd_id. Visite http://www.postgresql.org/docs/current/interactive/planner-stats-details.html para leer cómo funcionan las cosas. –

Cuestiones relacionadas