¿Cómo se crea una vista con SNAPSHOT_MATERIALIZATION en SQL Server 2017?


36

SQL Server 2017 tiene un par de nuevos procedimientos almacenados:

  • sp_refresh_single_snapshot_view - parámetro de entrada para @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - parámetro de entrada para @rgCode int

Y nuevas entradas en sys.messages:

  • 10149: el índice que tiene SNAPSHOT_MATERIALIZATION no se puede crear en la vista '%. * Ls' porque la definición de la vista contiene tablas optimizadas para la memoria.
  • 10642 - SNAPSHOT_MATERIALIZATION no se puede establecer para el índice '%. * Ls' en '%. * Ls' porque solo es aplicable a los índices en las vistas.
  • 10643 - SNAPSHOT_MATERIALIZATION no se puede establecer para '%. * Ls' en '%. * Ls' porque solo es aplicable a los índices agrupados en las vistas.
  • 10648 - SNAPSHOT_MATERIALIZATION no se puede establecer para el índice particionado '%. * Ls' en '%. * Ls'.
  • 10649: el índice no agrupado '%. * Ls' no se puede crear en '%. * Ls' que tiene el índice agrupado '%. * Ls' con SNAPSHOT_MATERIALIZATION.
  • 10650 - La actualización de las vistas de instantáneas requiere que el aislamiento de instantáneas esté habilitado en la base de datos.
  • 3760: no se puede eliminar el índice '%. * Ls' en la vista '%. * Ls' que tiene SNAPSHOT_MATERIALIZATION.
  • 4524: no se puede modificar la vista '%. * Ls' porque tiene materialización de instantánea.
  • 4525 - No se puede usar la sugerencia '% ls' en la vista '%. * Ls' que tiene materialización de instantánea antes de que se actualice la vista.

Y nuevos eventos extendidos:

Vista de instantánea Eventos extendidos

Entonces, ¿cómo podemos crear una vista materializada con instantáneas? (Microsoft aún no lo ha documentado, obviamente). Aquí hay una idea general de las cosas que he probado hasta ahora que no han funcionado.

Respuestas:


55

No puedes La función está deshabilitada en 2017 RTM.


Dicho eso, puedes ...

Usando AdventureWorks:

CREATE VIEW dbo.TH
WITH SCHEMABINDING
AS
SELECT P.ProductID, COUNT_BIG(*) AS cbs
FROM Production.Product AS P
JOIN Production.TransactionHistory AS TH
    ON TH.ProductID = P.ProductID
GROUP BY P.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Los cambios en las tablas subyacentes no se reflejan inmediatamente en la vista (como suele ser el caso con SQL Server). Del mismo modo, las modificaciones de datos en las tablas subyacentes no tienen que mantener la vista indizada de la instantánea.

Para actualizar el contenido de la vista, uno debe llamar a uno de los nuevos procedimientos almacenados:

EXECUTE sys.sp_refresh_single_snapshot_view
    @view_name = N'dbo.TH',
    @rgCode = 0; -- don't know what this is for yet

Esto produce el plan de ejecución:

Plan

Es probable que esto no funcione para usted, ya sea porque se necesita un indicador de rastreo indocumentado, o debe hacer lo particularmente desagradable que hice: escribir en la ubicación de la memoria que contiene el indicador de función (usando un depurador) para habilitar esta función.

Si tiene curiosidad, el indicador de función es el byte en sqllang!g_featureSwitchesLangSvc+0x10f. Se verifica durante sqllang!SpRefreshSingleSnapshotView.

Si desea seguir adelante y está completamente preparado para aceptar las consecuencias de piratear el código de SQL Server mientras se está ejecutando, y usar una función que Microsoft no cree que esté lista todavía:

  1. Adjunte un depurador al proceso de SQL Server 2017. Yo uso WinDbg.
  2. Establecer un punto de interrupción:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Reanude SQL Server con el comando Ir ( g)

  4. Cree la vista anterior, pero aún no el índice agrupado único
  5. Ejecute el sys.sp_refresh_single_snapshot_viewcomando anterior
  6. Cuando se alcanza el punto de interrupción, avance hasta que vea la línea de código:

    cmp byte ptr [sqllang!g_featureSwitchesLangSvc+0x10f (00007fff`328dfbcf)],0

    El desplazamiento puede ser diferente en otras versiones, por ejemplo, en 2017 RTM CU3 es sqllang!g_featureSwitchesLangSvc+0x114

  7. La dirección de memoria dentro de los paréntesis puede ser diferente. Usa el que ves.

  8. Use el comando display memory para ver el valor actual en la dirección de memoria que encontró:

    db 00007fff`328dfbcf L1
  9. Esto debería mostrar un cero, lo que indica que la función está deshabilitada.

  10. Cambie el cero a uno, usando el comando enter values ​​(nuevamente con su dirección de memoria):

    eb 00007fff`328dfbcf 1
  11. Deshabilite el punto de interrupción y reanude la ejecución de SQL Server.

  12. La función ahora está habilitada.
  13. Cree el índice agrupado único en la vista.
  14. Jugar.

Note SNAPSHOT_MATERIALIZATIONnos permite materializar una instantánea de una especificación de consulta que normalmente no se puede indexar, por ejemplo, los siguientes usos MAX:

CREATE VIEW dbo.TH2
WITH SCHEMABINDING
AS
SELECT TH.ProductID, MaxTransactionID = MAX(TH.TransactionID)
FROM Production.TransactionHistory AS TH
GROUP BY TH.ProductID;
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.TH2 (ProductID)
WITH (SNAPSHOT_MATERIALIZATION = ON);

Resultado:

Comandos completados con éxito.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.