Jak utworzyć widok za pomocą SNAPSHOT_MATERIALIZATION w SQL Server 2017?

36

SQL Server 2017 ma kilka nowych procedur przechowywanych:

  • sp_refresh_single_snapshot_view - parametr wejściowy dla @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - parametr wejściowy dla @rgCode int

I nowe wpisy w sys.messages:

  • 10149 - Nie można utworzyć indeksu z SNAPSHOT_MATERIALIZATION w widoku „%. * Ls, ponieważ definicja widoku zawiera tabele zoptymalizowane pod kątem pamięci.
  • 10642 - Nie można ustawić SNAPSHOT_MATERIALIZATION dla indeksu „%. * Ls w„%. * Ls, ponieważ ma on zastosowanie tylko do indeksów w widokach.
  • 10643 - Nie można ustawić SNAPSHOT_MATERIALIZATION dla „%. * Ls na„%. * Ls, ponieważ ma to zastosowanie tylko do indeksów klastrowych w widokach.
  • 10648 - Nie można ustawić SNAPSHOT_MATERIALIZATION dla indeksu partycjonowanego „%. * Ls na„%. * Ls.
  • 10649 - Nieklastrowanego indeksu „%. * Ls nie można utworzyć na„%. * Ls ”, który ma indeks klastrowany„%. * Ls z SNAPSHOT_MATERIALIZATION.
  • 10650 - Odświeżanie widoków migawek wymaga włączenia izolacji migawki w bazie danych.
  • 3760 - Nie można upuścić indeksu „%. * Ls w widoku„%. * Ls ”, który ma SNAPSHOT_MATERIALIZATION.
  • 4524 - Nie można zmienić widoku '%. * Ls, ponieważ ma on materializację migawki.
  • 4525 - Nie można użyć podpowiedzi „% ls” w widoku „%. * Ls, który ma materializację migawki przed odświeżeniem widoku.

I nowe wydarzenia rozszerzone:

Widok migawki Rozszerzone zdarzenia

Jak więc stworzyć widok zmaterializowany w migawce? (Microsoft oczywiście tego jeszcze nie udokumentował.) Oto sedno rzeczy, których do tej pory próbowałem, ale które nie zadziałały.

Brent Ozar
źródło

Odpowiedzi:

55

Nie możesz Ta funkcja jest wyłączona w 2017 RTM.


To powiedziawszy, możesz ...

Korzystanie z 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);

Zmiany w bazowych tabelach nie są natychmiast odzwierciedlane w widoku (jak zwykle w przypadku SQL Server). Podobnie modyfikacje danych w bazowych tabelach nie muszą utrzymywać widoku indeksowanego migawki.

Aby odświeżyć zawartość widoku, należy wywołać jedną z nowych procedur przechowywanych:

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

Spowoduje to utworzenie planu wykonania:

Plan

Prawdopodobnie to nie zadziała, ponieważ potrzebna jest albo nieudokumentowana flaga śledzenia, albo musisz zrobić szczególnie nieprzyjemną rzecz, którą zrobiłem: pisanie do lokalizacji pamięci z flagą funkcji (za pomocą debugera), aby włączyć tę funkcję.

Jeśli jesteś ciekawy, flaga funkcji to bajt w sqllang!g_featureSwitchesLangSvc+0x10f. Jest sprawdzany podczas sqllang!SpRefreshSingleSnapshotView.

Jeśli chcesz grać dalej i jesteś w pełni przygotowany do zaakceptowania konsekwencji włamania się do kodu programu SQL Server podczas jego działania i korzystania z funkcji, która według Microsoft nie jest jeszcze gotowa:

  1. Dołącz debuger do procesu SQL Server 2017. Używam WinDbg.
  2. Ustaw punkt przerwania:

    bp sqllang!SpRefreshSingleSnapshotView
  3. Wznów SQL Server za pomocą polecenia Go ( g)

  4. Utwórz widok powyżej, ale jeszcze nie unikalny indeks klastrowany
  5. Uruchom sys.sp_refresh_single_snapshot_viewpolecenie powyżej
  6. Po osiągnięciu punktu przerwania przejdź przez linię, aż zobaczysz linię kodu:

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

    Przesunięcie może być inne w innych kompilacjach, na przykład w 2017 RTM CU3 sqllang!g_featureSwitchesLangSvc+0x114

  7. Adres pamięci w nawiasach może być inny. Użyj tego, który widzisz.

  8. Użyj polecenia display memory, aby zobaczyć bieżącą wartość pod znalezionym adresem pamięci:

    db 00007fff`328dfbcf L1
  9. Powinno to pokazywać zero, co oznacza, że ​​funkcja jest wyłączona.

  10. Zmień zero na jeden, używając polecenia Enter wartości (ponownie z adresem pamięci):

    eb 00007fff`328dfbcf 1
  11. Wyłącz punkt przerwania i wznów działanie programu SQL Server.

  12. Ta funkcja jest teraz włączona.
  13. Zbuduj unikalny indeks klastrowy w widoku.
  14. Bawić.

Uwaga SNAPSHOT_MATERIALIZATIONpozwala nam zmaterializować migawkę specyfikacji zapytania, której zwykle nie można indeksować, na przykład poniższe zastosowania 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);

Wynik:

Polecenia zostały wykonane pomyślnie.
Paul White mówi GoFundMonica
źródło