Come si crea una vista con SNAPSHOT_MATERIALIZATION in SQL Server 2017?


36

SQL Server 2017 ha un paio di nuove procedure memorizzate:

  • sp_refresh_single_snapshot_view - input param per @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - input param per @rgCode int

E nuove voci in sys.messages:

  • 10149 - L'indice con SNAPSHOT_MATERIALIZATION non può essere creato sulla vista '%. * Ls' perché la definizione della vista contiene tabelle ottimizzate per la memoria.
  • 10642 - SNAPSHOT_MATERIALIZATION non può essere impostato per l'indice '%. * Ls' su '%. * Ls' perché è applicabile solo agli indici nelle viste.
  • 10643 - SNAPSHOT_MATERIALIZATION non può essere impostato per '%. * Ls' su '%. * Ls' perché è applicabile solo agli indici cluster nelle viste.
  • 10648 - SNAPSHOT_MATERIALIZATION non può essere impostato per l'indice partizionato '%. * Ls' su '%. * Ls'.
  • 10649 - L'indice non cluster '%. * Ls' non può essere creato su '%. * Ls' che ha un indice cluster '%. * Ls' con SNAPSHOT_MATERIALIZATION.
  • 10650 - L'aggiornamento delle viste delle istantanee richiede che l'isolamento delle istantanee sia abilitato sul database.
  • 3760 - Impossibile eliminare l'indice '%. * Ls' nella vista '%. * Ls' con SNAPSHOT_MATERIALIZATION.
  • 4524 - Impossibile modificare la vista '%. * Ls' perché ha materializzazione istantanea.
  • 4525 - Impossibile utilizzare il suggerimento '% ls' sulla vista '%. * Ls' che ha materializzazione istantanea prima che la vista venga aggiornata.

E nuovi eventi estesi:

Visualizzazione istantanea Eventi estesi

Quindi, come possiamo creare una vista materializzata da un'istantanea? (Microsoft non lo ha ancora documentato, ovviamente.) Ecco un riassunto delle cose che ho provato finora che non hanno funzionato.

Risposte:


55

Non puoi. La funzione è disabilitata nel 2017 RTM.


Detto questo, puoi ...

Utilizzando 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);

Le modifiche alle tabelle sottostanti non si riflettono immediatamente nella vista (come avviene normalmente con SQL Server). Allo stesso modo, le modifiche ai dati rispetto alle tabelle sottostanti non devono mantenere la vista indicizzata dello snapshot.

Per aggiornare i contenuti della vista, è necessario chiamare una delle nuove procedure memorizzate:

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

Questo produce il piano di esecuzione:

Piano

Questo probabilmente non funzionerà per te, perché è necessario un flag di traccia non documentato o devi fare la cosa particolarmente brutta che ho fatto: scrivere nella posizione di memoria con il flag di funzionalità (usando un debugger) per abilitare questa funzione.

Se sei curioso, il flag funzione è il byte in sqllang!g_featureSwitchesLangSvc+0x10f. Viene controllato durante sqllang!SpRefreshSingleSnapshotView.

Se vuoi giocare insieme e sei completamente pronto ad accettare le conseguenze dell'hacking nel codice di SQL Server mentre è in esecuzione e utilizzando una funzionalità che Microsoft non pensa sia ancora pronta:

  1. Collegare un debugger al processo di SQL Server 2017. Uso WinDbg.
  2. Imposta un punto di interruzione:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Riprendi SQL Server utilizzando il comando Vai ( g)

  4. Crea la vista sopra, ma non ancora l'indice cluster univoco
  5. Esegui il sys.sp_refresh_single_snapshot_viewcomando sopra
  6. Quando viene raggiunto il punto di interruzione, scorrere fino a visualizzare la riga di codice:

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

    L'offset può essere diverso in altre build, ad esempio nel 2017 RTM CU3 lo è sqllang!g_featureSwitchesLangSvc+0x114

  7. L'indirizzo di memoria tra parentesi potrebbe essere diverso. Usa quello che vedi.

  8. Usa il comando display memory per vedere il valore corrente all'indirizzo di memoria che hai trovato:

    db 00007fff`328dfbcf L1
  9. Questo dovrebbe mostrare uno zero, a indicare che la funzione è disabilitata.

  10. Cambia lo zero in uno, usando il comando immetti valori (di nuovo con il tuo indirizzo di memoria):

    eb 00007fff`328dfbcf 1
  11. Disabilitare il punto di interruzione e riprendere l'esecuzione di SQL Server.

  12. La funzione è ora abilitata.
  13. Crea l'indice cluster univoco sulla vista.
  14. Divertirsi.

Nota SNAPSHOT_MATERIALIZATIONci consente di materializzare un'istantanea di una specifica di query che normalmente non può essere indicizzata, ad esempio i seguenti usi 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);

Risultato:

Comandi completati correttamente.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.