Como você cria uma exibição com SNAPSHOT_MATERIALIZATION no SQL Server 2017?

36

O SQL Server 2017 possui alguns novos procedimentos armazenados:

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

E novas entradas no sys.messages:

  • 10149 - O índice que possui SNAPSHOT_MATERIALIZATION não pode ser criado na visualização '%. * Ls' porque a definição de visualização contém tabelas com otimização de memória.
  • 10642 - SNAPSHOT_MATERIALIZATION não pode ser definido para o índice '%. * Ls' em '%. * Ls' porque é aplicável apenas aos índices nas visualizações.
  • 10643 - SNAPSHOT_MATERIALIZATION não pode ser definido para '%. * Ls' em '%. * Ls' porque é aplicável apenas a índices agrupados em visualizações.
  • 10648 - SNAPSHOT_MATERIALIZATION não pode ser definido para o índice particionado '%. * Ls' em '%. * Ls'.
  • 10649 - O índice não clusterizado '%. * Ls' não pode ser criado em '%. * Ls' que agrupou o índice '%. * Ls' com SNAPSHOT_MATERIALIZATION.
  • 10650 - A atualização da (s) visualização (ões) de captura instantânea requer que o isolamento de captura instantânea seja ativado no banco de dados.
  • 3760 - Não é possível descartar o índice '%. * Ls' na exibição '%. * Ls' que possui SNAPSHOT_MATERIALIZATION.
  • 4524 - Não é possível alterar a exibição '%. * Ls' porque possui materialização de captura instantânea.
  • 4525 - Não é possível usar a dica '% ls' na exibição '%. * Ls' que possui materialização de captura instantânea antes que a exibição seja atualizada.

E novos eventos estendidos:

Visualização de instantâneo Eventos estendidos

Então, como podemos criar uma visualização materializada por snapshot? (A Microsoft ainda não documentou isso, obviamente.) Aqui está um resumo das coisas que tentei até agora e que não funcionaram.

Brent Ozar
fonte

Respostas:

55

Você não pode. O recurso está desativado no 2017 RTM.


Dito isto, você pode ...

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

As alterações nas tabelas subjacentes não são refletidas imediatamente na exibição (como normalmente ocorre no SQL Server). Da mesma forma, as modificações de dados nas tabelas subjacentes não precisam manter a exibição indexada da captura instantânea.

Para atualizar o conteúdo da visualização, é necessário chamar um dos novos procedimentos armazenados:

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

Isso produz o plano de execução:

Plano

Isso provavelmente não funcionará para você, porque é necessário um sinalizador de rastreamento não documentado ou você precisa fazer a coisa mais desagradável que eu fiz: gravar no local da memória segurando o sinalizador de recurso (usando um depurador) para habilitá-lo.

Se você estiver curioso, o sinalizador do recurso é o byte em sqllang!g_featureSwitchesLangSvc+0x10f. É verificado durante sqllang!SpRefreshSingleSnapshotView.

Se você deseja jogar junto e está totalmente preparado para aceitar as consequências de invadir o código do SQL Server enquanto ele estiver em execução e usar um recurso que a Microsoft ainda não acha que está pronto:

  1. Anexe um depurador ao processo do SQL Server 2017. Eu uso o WinDbg.
  2. Defina um ponto de interrupção:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Reinicie o SQL Server usando o comando Go ( g)

  4. Crie a visualização acima, mas ainda não o índice clusterizado exclusivo
  5. Execute o sys.sp_refresh_single_snapshot_viewcomando acima
  6. Quando o ponto de interrupção for atingido, avance até ver a linha do código:

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

    O deslocamento pode ser diferente em outras construções, por exemplo, em 2017 RTM CU3, é sqllang!g_featureSwitchesLangSvc+0x114

  7. O endereço da memória entre parênteses pode ser diferente. Use o que você vê.

  8. Use o comando display memory para ver o valor atual no endereço de memória que você encontrou:

    db 00007fff`328dfbcf L1
  9. Isso deve mostrar um zero, indicando que o recurso está desativado.

  10. Altere o zero para um, usando o comando enter values ​​(novamente com seu endereço de memória):

    eb 00007fff`328dfbcf 1
  11. Desabilite o ponto de interrupção e continue executando o SQL Server.

  12. O recurso agora está ativado.
  13. Crie o índice clusterizado exclusivo na exibição.
  14. Brinque.

A observação SNAPSHOT_MATERIALIZATIONnos permite materializar um instantâneo de uma especificação de consulta que normalmente não pode ser indexada, por exemplo, os usos abaixo 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 concluídos com sucesso.
Paul White diz que a GoFundMonica
fonte