Sql-Server

如何在 SQL Server 2017 中使用 SNAPSHOT_MATERIALIZATION 創建視圖?

  • February 10, 2018

SQL Server 2017 有幾個新的儲存過程:

  • sp_refresh_single_snapshot_view – @view_name nvarchar(261)、@rgCode int 的輸入參數
  • sp_refresh_snapshot_views – @rgCode int 的輸入參數

sys.messages 中的新條目:

  • 10149 – 無法在視圖 ‘%.*ls’ 上創建具有 SNAPSHOT_MATERIALIZATION 的索引,因為視圖定義包含記憶體優化表。
  • 10642 – 不能為 ‘%.*ls’ 上的索引 ‘%.*ls’ 設置 SNAPSHOT_MATERIALIZATION,因為它僅適用於視圖上的索引。
  • 10643 – 不能為 ‘%.*ls’ 上的 ‘%.*ls’ 設置 SNAPSHOT_MATERIALIZATION,因為它僅適用於視圖上的聚集索引。
  • 10648 – 不能為 ‘%.*ls’ 上的分區索引 ‘%.*ls’ 設置 SNAPSHOT_MATERIALIZATION。
  • 10649 – 無法在具有 SNAPSHOT_MATERIALIZATION 的聚集索引 ‘%.*ls’ 的 ‘%.*ls’ 上創建非聚集索引 ‘%.*ls’。
  • 10650 – 刷新快照視圖需要在數據庫上啟用快照隔離。
  • 3760 – 無法刪除具有 SNAPSHOT_MATERIALIZATION 的視圖 ‘%.*ls’ 上的索引 ‘%.*ls’。
  • 4524 – 無法更改視圖 ‘%.*ls’,因為它具有快照實現。
  • 4525 – 在刷新視圖之前,無法對具有快照實現的視圖 ‘%.*ls’ 使用提示 ‘%ls’。

和新的擴展事件:

快照視圖擴展事件

那麼我們如何創建快照物化視圖呢?(顯然,微軟還沒有記錄它。)這是我迄今為止嘗試過的東西的要點

你不能。該功能在 2017 RTM 中被禁用。


也就是說,你可以…

使用 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
  1. g使用 Go 命令 ( )恢復 SQL Server
  2. 創建上面的視圖,但還沒有唯一的聚集索引
  3. 執行sys.sp_refresh_single_snapshot_view上面的命令
  4. 當斷點被命中時,單步執行直到看到程式碼行:
cmp byte ptr [sqllang!g_featureSwitchesLangSvc+0x10f (00007fff`328dfbcf)],0

其他版本中的偏移量可能會有所不同,例如在 2017 RTM CU3 中sqllang!g_featureSwitchesLangSvc+0x114 7. 括號內的記憶體地址可能不同。使用你看到的那個。 8. 使用 display memory 命令查看找到的記憶體地址處的目前值:

db 00007fff`328dfbcf L1
  1. 這應該顯示一個零,表示該功能已禁用。
  2. 使用 enter values 命令(再次使用您的記憶體地址)將零更改為一:
eb 00007fff`328dfbcf 1
  1. 禁用斷點並繼續執行 SQL Server。
  2. 該功能現已啟用。
  3. 在視圖上建構唯一聚集索引。
  4. 到處玩。

注意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);

結果:

命令成功完成。

引用自:https://dba.stackexchange.com/questions/187533