如何在SQL Server 2017中使用SNAPSHOT_MATERIALIZATION创建视图?


36

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'。

以及新的扩展事件:

快照视图扩展事件

那么我们如何创建快照实现的视图呢?(显然,Microsoft尚未对此进行记录。)这是我迄今为止尝试过但仍未奏效的要点

Answers:


55

你不能 该功能已在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
  3. 使用Go命令(g)恢复SQL Server

  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. 使用display memory命令可以在找到的内存地址上查看当前值:

    db 00007fff`328dfbcf L1
  9. 这应该显示为零,表示该功能已禁用。

  10. 使用enter values命令(再次使用您的内存地址)将零更改为1:

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

结果:

命令成功完成。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.