Sql-Server
如何在 SQL Server 2017 中使用 SNAPSHOT_MATERIALIZATION 創建視圖?
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 認為尚未準備好的功能:
- 將調試器附加到 SQL Server 2017 程序。我使用WinDbg。
- 設置斷點:
bp sqllang!SpRefreshSingleSnapshotView
g
使用 Go 命令 ( )恢復 SQL Server- 創建上面的視圖,但還沒有唯一的聚集索引
- 執行
sys.sp_refresh_single_snapshot_view
上面的命令- 當斷點被命中時,單步執行直到看到程式碼行:
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
- 這應該顯示一個零,表示該功能已禁用。
- 使用 enter values 命令(再次使用您的記憶體地址)將零更改為一:
eb 00007fff`328dfbcf 1
- 禁用斷點並繼續執行 SQL Server。
- 該功能現已啟用。
- 在視圖上建構唯一聚集索引。
- 到處玩。
注意
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);
結果:
命令成功完成。