¿Cómo crear vistas materializadas en SQL Server?

101

Voy a diseñar un DW y escuché sobre vistas materializadas. En realidad, quiero crear una vista y debería actualizarse automáticamente cuando se cambian las tablas base. ¿Alguien puede explicar con un ejemplo de consulta?

Deepak
fuente

Respuestas:

144

Se denominan vistas indexadas en SQL Server; lea estos documentos técnicos para obtener más información:

Básicamente, todo lo que necesitas hacer es:

  • crear una vista regular
  • crear un índice agrupado en esa vista

¡y tu estas listo!

La parte complicada es: la vista tiene que satisfacer una gran cantidad de restricciones y limitaciones, que se describen en el documento técnico. Si haces esto, eso es todo lo que hay. La vista se actualiza automáticamente, no se necesita mantenimiento.

Recursos adicionales:

marc_s
fuente
Gracias por su respuesta. Conseguí lo que quiero ... También me gustaría saber sobre índices. Quiero saber, ¿hay alguna forma de generar un diagrama de esquema en estrella en el servidor SQL cuando tenga toda la estructura de la tabla lista? Si es así, ¿cómo creo una tabla de hechos para eso?
Deepak
3
Las restricciones para poner un índice agrupado en la vista son amplias. Por ejemplo, la vista no puede hacer referencia a otras vistas y no puede contener combinaciones externas. Por tanto, muchas vistas que necesitan un mejor rendimiento no pueden utilizar este método. Sigue siendo una buena respuesta.
Jeff Wilson
1
Como se menciona en una pregunta relacionada, el artículo del blog de MSDN, blogs.msdn.microsoft.com/ssma/2011/06/20/… , destaca algunas de las diferencias clave entre las vistas materializadas y las vistas indexadas. En mi humilde opinión, el más problemático es no poder especificar activadores de actualización: las vistas indexadas se actualizan cada vez que se actualizan las tablas base, lo que socava la mayoría de los beneficios de rendimiento de usar una vista materializada. Las prohibiciones de combinaciones, agregados, funciones de ventanas y subconsultas hacen que las vistas indexadas sean casi inútiles a menos que los datos no cambien con frecuencia.
Suncat2000
43

Aunque puramente desde la perspectiva de la ingeniería, las vistas indexadas suenan como algo que todos podrían usar para mejorar el rendimiento, pero el escenario de la vida real es muy diferente. No he tenido éxito al usar vistas indexadas donde más las necesito debido a demasiadas restricciones sobre lo que se puede indexar y lo que no.

Si tiene uniones externas en las vistas, no se pueden utilizar. Además, las expresiones de tabla comunes no están permitidas ... De hecho, si tiene algún orden en subselecciones o tablas derivadas (como con partición por cláusula), tampoco tiene suerte.

Eso deja solo escenarios muy simples para utilizar vistas indexadas, algo en mi opinión se puede optimizar creando índices adecuados en las tablas subyacentes de todos modos.

Me encantará escuchar algunos escenarios de la vida real en los que las personas realmente han utilizado vistas indexadas para su beneficio y no podrían haberlo hecho sin ellas.

Rajiv
fuente
En realidad, he usado vistas indexadas (solo una vez) para particionar un índice de búsqueda de texto completo. De hecho, los índices FTS no se pueden particionar, pero se pueden crear índices separados en varias vistas de la misma tabla. Sin embargo, fue una especie de último recurso.
areyesram
4
Debe recordar agregar (NOEXPAND)pistas a las consultas que usan las vistas indexadas. Y luego notas la diferencia. La ventaja de usar las vistas indexadas frente a "indexar correctamente las tablas" es que limita la selección de registros, de lo contrario está en lo correcto, sería lo mismo.
ajeh
¡Sí, lo de NOEXPAND no puede subestimarse!
Simon_Weaver
18

Es posible que necesite un poco más de información sobre lo que es realmente una Vista materializada. En Oracle, estos son un objeto que consta de una serie de elementos cuando intenta construirlo en otro lugar.

Un MVIEW es esencialmente una instantánea de datos de otra fuente. A diferencia de una vista, los datos no se encuentran cuando consulta la vista, se almacena localmente en forma de tabla. El MVIEW se actualiza mediante un procedimiento en segundo plano que comienza a intervalos regulares o cuando cambian los datos de origen. Oracle permite actualizaciones completas o parciales.

En SQL Server, usaría lo siguiente para crear un MVIEW básico para (completar) actualizar regularmente.

Primero, una vista. Esto debería ser fácil para la mayoría, ya que las vistas son bastante comunes en cualquier base de datos. Siguiente, una tabla. Debe ser idéntica a la vista en columnas y datos. Esto almacenará una instantánea de los datos de la vista. Luego, un procedimiento que trunca la tabla y la vuelve a cargar en función de los datos actuales en la vista. Finalmente, un trabajo que activa el procedimiento para iniciar su trabajo.

Todo lo demás es experimentación.

Jason A.
fuente
5
Sus comentarios sobre SQL Server son incorrectos: las vistas materializadas son cosas muy diferentes en Oracle y SQL Server. En SQL Server, una vista con un índice agrupado único en ella (también conocida como "vista materializada") no puede ser actualizada por el usuario, ni se almacena en una tabla separada creada por el usuario; siempre la actualiza el motor durante las actualizaciones y nunca está desincronizado. No es necesario que haya ningún trabajo para almacenar una instantánea de los datos.
ErikE
10
Lo que pidió el OP lo proporciona fácilmente una vista indexada. Eso es lo más parecido que ofrece SQL Server de forma nativa a una vista materializada de Oracle. Sin embargo, si desea / necesita replicar exactamente la forma en que funciona un MVIEW de Oracle, Jason tiene razón. El enfoque de Jason también ayuda en el mismo escenario que los MVIEW de Oracle pueden, por ejemplo, actualizar fuera de horario una tabla de informes en la que le importa más la carga de la base de datos que la actualización de la vista (por ejemplo, informar solo sobre los números de ayer ...)
4

Cuando la vista indexada no es una opción y las actualizaciones rápidas no son necesarias, puede crear una tabla de caché de pirateo:

select * into cachetablename from myviewname
alter table cachetablename add primary key (columns)
-- OR alter table cachetablename add rid bigint identity primary key
create index...

luego sp_rename view / table o cambie cualquier consulta u otra vista que haga referencia a ella para que apunte a la tabla de caché.

programar diario / nocturno / semanal / lo que no se actualice como

begin transaction
truncate table cachetablename
insert into cachetablename select * from viewname
commit transaction

NB: esto consumirá espacio, también en sus registros de tx. Se utiliza mejor para pequeños conjuntos de datos que son lentos de calcular. Tal vez refactorice para eliminar las columnas "fáciles pero grandes" primero en una vista exterior.

estox
fuente
1

Para MS T-SQL Server, sugiero buscar en la creación de un índice con la declaración "incluir". No se requiere unicidad, ni tampoco la clasificación física de los datos asociados con un índice agrupado. El "Índice ... Incluir ()" crea un almacenamiento de datos físicos separado mantenido automáticamente por el sistema. Es conceptualmente muy similar a una vista materializada de Oracle.

https://msdn.microsoft.com/en-us/library/ms190806.aspx

https://technet.microsoft.com/en-us/library/ms189607(v=sql.105).aspx

Scott Nightlinger
fuente