Wie erstelle ich eine Ansicht mit SNAPSHOT_MATERIALIZATION in SQL Server 2017?

36

SQL Server 2017 verfügt über einige neue gespeicherte Prozeduren:

  • sp_refresh_single_snapshot_view - Eingabeparameter für @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - Eingabeparameter für @rgCode int

Und neue Einträge in sys.messages:

  • 10149 - Ein Index mit SNAPSHOT_MATERIALIZATION kann für die Sicht '%. * Ls' nicht erstellt werden, da die Sichtdefinition speicheroptimierte Tabellen enthält.
  • 10642 - SNAPSHOT_MATERIALIZATION kann nicht für den Index '%. * Ls' für '%. * Ls' festgelegt werden, da er nur für Indizes für Ansichten gilt.
  • 10643 - SNAPSHOT_MATERIALIZATION kann nicht für '%. * Ls' in '%. * Ls' festgelegt werden, da es nur für Clustered-Indizes für Ansichten gilt.
  • 10648 - SNAPSHOT_MATERIALIZATION kann nicht für den partitionierten Index '%. * Ls' für '%. * Ls' festgelegt werden.
  • 10649 - Der nicht gruppierte Index '%. * Ls' kann nicht für '%. * Ls' erstellt werden, für den der Index '%. * Ls' mit SNAPSHOT_MATERIALIZATION gruppiert wurde.
  • 10650 - Für die Aktualisierung von Snapshot-Ansichten muss die Snapshot-Isolation in der Datenbank aktiviert sein.
  • 3760 - Der Index '%. * Ls' für die Ansicht '%. * Ls' mit SNAPSHOT_MATERIALIZATION kann nicht gelöscht werden.
  • 4524 - Die Ansicht '%. * Ls' kann nicht geändert werden, da sie über eine Momentaufnahme-Materialisierung verfügt.
  • 4525 - Hinweis '% ls' für Ansicht '%. * Ls' mit Momentaufnahme-Materialisierung kann nicht verwendet werden, bevor die Ansicht aktualisiert wird.

Und neue Extended Events:

Snapshot-Ansicht Erweiterte Ereignisse

Also, wie können wir eine Snapshot-materialisierte Ansicht erstellen? (Microsoft hat es offensichtlich noch nicht dokumentiert.) Hier ist eine Zusammenfassung der Dinge, die ich bisher ausprobiert habe und die nicht funktioniert haben.

Brent Ozar
quelle

Antworten:

55

Das kannst du nicht. Die Funktion ist in 2017 RTM deaktiviert.


Das heißt, Sie können ...

Verwenden von 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);

Änderungen an den zugrunde liegenden Tabellen werden nicht sofort in die Ansicht übernommen (wie dies normalerweise bei SQL Server der Fall ist). Ebenso müssen Datenänderungen an den zugrunde liegenden Tabellen die indizierte Snapshot-Ansicht nicht beibehalten.

Um den Inhalt der Ansicht zu aktualisieren, muss eine der neuen gespeicherten Prozeduren aufgerufen werden:

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

Dies ergibt den Ausführungsplan:

Planen

Dies funktioniert bei Ihnen wahrscheinlich nicht, da entweder ein nicht dokumentiertes Ablaufverfolgungsflag erforderlich ist oder Sie das besonders unangenehme tun müssen, das ich getan habe: In den Speicherort schreiben, der das Feature-Flag enthält (mit einem Debugger), um dieses Feature zu aktivieren.

Wenn Sie neugierig sind, ist das Feature-Flag das Byte bei sqllang!g_featureSwitchesLangSvc+0x10f. Es wird während geprüft sqllang!SpRefreshSingleSnapshotView.

Wenn Sie mitspielen möchten und bereit sind, die Konsequenzen von Hackerangriffen im laufenden SQL Server-Code zu akzeptieren und eine Funktion zu verwenden, die Microsoft noch nicht für bereit hält:

  1. Hängen Sie einen Debugger an den SQL Server 2017-Prozess an. Ich benutze WinDbg.
  2. Legen Sie einen Haltepunkt fest:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Setzen Sie SQL Server mit dem Befehl Go ( g) fort.

  4. Erstellen Sie die obige Ansicht, jedoch noch nicht den eindeutigen Clustered-Index
  5. Führen Sie den sys.sp_refresh_single_snapshot_viewobigen Befehl aus
  6. Wenn der Haltepunkt erreicht ist, gehen Sie weiter, bis Sie die Codezeile sehen:

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

    Der Versatz kann in anderen Builds unterschiedlich sein, z. B. in 2017 RTM CU3 sqllang!g_featureSwitchesLangSvc+0x114

  7. Die Speicheradresse in den Klammern kann unterschiedlich sein. Verwenden Sie den, den Sie sehen.

  8. Verwenden Sie den Befehl display memory, um den aktuellen Wert an der gefundenen Speicheradresse anzuzeigen:

    db 00007fff`328dfbcf L1
  9. Dies sollte eine Null anzeigen, was darauf hinweist, dass die Funktion deaktiviert ist.

  10. Ändern Sie die Null mit dem Befehl enter values ​​(wieder mit Ihrer Speicheradresse) in eine Eins:

    eb 00007fff`328dfbcf 1
  11. Deaktivieren Sie den Haltepunkt und setzen Sie die Ausführung von SQL Server fort.

  12. Die Funktion ist jetzt aktiviert.
  13. Erstellen Sie den eindeutigen Clustered-Index für die Ansicht.
  14. Herumspielen.

Hinweis: SNAPSHOT_MATERIALIZATIONErmöglicht die Erstellung eines Snapshots einer Abfragespezifikation, die normalerweise nicht indiziert werden konnte. Beispiel 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);

Ergebnis:

Befehle erfolgreich ausgeführt.
Paul White sagt GoFundMonica
quelle