Как создать представление с помощью SNAPSHOT_MATERIALIZATION в SQL Server 2017?

SQL Server 2017 имеет пару новых хранимых процедур:

  • sp_refresh_single_snapshot_view - входной параметр для @view_name nvarchar (261), @rgCode int
  • sp_refresh_snapshot_views - входной параметр для @rgCode int

И новые записи в sys.messages:

  • 10149 - Индекс, который имеет SNAPSHOT_MATERIALIZATION, не может быть создан на вид â €%%. * lsâ € ™, потому что определение представления содержит оптимизированные по памяти таблицы (ы).
  • 10642 - SNAPSHOT_MATERIALIZATION не может быть задан для индекса â%. * lsâ € ™ on â €%%. * lsâ € ™, потому что он применим только к индексам в представлениях.
  • 10643 - SNAPSHOT_MATERIALIZATION не может быть установлен для «%». * lsâ € ™ on â €%%. * lsâ € ™, потому что он применим только к кластерным индексам в представлениях.
  • 10648 - SNAPSHOT_MATERIALIZATION не может быть задан для секционированного индекса â €%. * lsâ € ™ на ~%. * lsâ € ™.
  • 10649 - Некластеризованный индекс â €%. * lsâ € ™ не может быть создан на «%. * ls», который имеет кластерный индекс â €%. * lsâ € ™ с SNAPSHOT_MATERIALIZATION.
  • 10650 - Refresh of snapshot view (s) требует, чтобы в базе данных была включена блокировка моментальных снимков.
  • 3760 - Невозможно отказаться от индекса â%. * lsâ € ™ на вид â €%. * lsâ € ™, который имеет SNAPSHOT_MATERIALIZATION.
  • 4524 - Невозможно изменить вид -%. * lsâ € ™, потому что он имеет материализацию моментальных снимков.
  • 4525 - Невозможно использовать подсказку -% lsâ € ™ on view â €%. * lsâ € ™, которая имеет материализацию моментального снимка перед обновлением представления.

И новые расширенные события:

 Просмотр снимков Расширенные события

Итак, как мы можем создать представление, сделанное с моментальным снимком? (Microsoft пока не задокументировала это.) Вот сущность, которую я пробовал до сих пор которые не работали.

35 голосов | спросил Brent Ozar 3 +03002017-10-03T17:47:30+03:00312017bEurope/MoscowTue, 03 Oct 2017 17:47:30 +0300 2017, 17:47:30

1 ответ


52

Вы не можете. Функция отключена в RTM 2017.


Тем не менее, вы можете ...

Использование 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);

Изменения в базовых таблицах не сразу отражаются в представлении (как это обычно бывает в SQL Server). Аналогичным образом, модификации данных в отношении базовых таблиц не должны поддерживать индексированный снимок.

Чтобы обновить содержимое представления, нужно вызвать одну из новых хранимых процедур:

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

Это создает план выполнения:

 План

Вероятно, это не сработает для вас, потому что нужен недопустимый флаг трассировки, или вам нужно сделать особенно неприятную вещь, которую я сделал: запись в ячейку памяти, содержащую флаг функции (с помощью отладчика), чтобы включить это особенность.

Если вам интересно, флаг функции - это байт в sqllang!g_featureSwitchesLangSvc+0x10f. Он проверяется во время sqllang!SpRefreshSingleSnapshotView.

Если вы хотите играть вместе и полностью готовы принять последствия взлома кода SQL Server во время его работы и использовать функцию, которую Microsoft не считает готовой:

  1. Прикрепите отладчик к процессу SQL Server 2017. Я использую WinDbg.
  2. Установить точку останова:

    bp sqllang!SpRefreshSingleSnapshotView
    
  3. Возобновить SQL Server с помощью команды Go (g)

  4. Создайте представление выше, но не уникальный кластеризованный индекс еще
  5. Запустите команду sys.sp_refresh_single_snapshot_view выше
  6. Когда точка останова будет нажата, пройдите, пока не увидите строку кода:

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

    Смещение может быть другим в других сборках, например, в 2017 году RTM CU3 это sqllang!g_featureSwitchesLangSvc+0x114

  7. Адрес памяти в круглых скобках может отличаться. Используйте тот, который вы видите.

  8. Используйте команду памяти дисплея, чтобы увидеть текущее значение по адресу памяти, который вы нашли:

    db 00007fff`328dfbcf L1
    
  9. Это должно показывать нуль, указывая, что функция отключена.

  10. Измените ноль на единицу, используя команду ввода значений (снова с адресом вашей памяти):

    eb 00007fff`328dfbcf 1
    
  11. Отключите точку останова и возобновите запуск SQL Server.

  12. Теперь функция включена.
  13. Создайте уникальный кластерный индекс в представлении.
  14. Играйте вокруг.

Примечание SNAPSHOT_MATERIALIZATION позволяет нам реализовать снимок спецификации запроса, который обычно не может быть проиндексирован, например, ниже используется 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);

Результат:

Команды успешно завершены.
ответил Paul White 3 +03002017-10-03T18:14:01+03:00312017bEurope/MoscowTue, 03 Oct 2017 18:14:01 +0300 2017, 18:14:01

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132