SQL Server 2017 has a couple new stored procedures:
- sp_refresh_single_snapshot_view – input param for @view_name nvarchar(261), @rgCode int
- sp_refresh_snapshot_views – input param for @rgCode int
And new entries in sys.messages:
- 10149 – Index that has SNAPSHOT_MATERIALIZATION cannot be created on view ‘%.*ls’ because view definition contains memory-optimized table(s).
- 10642 – SNAPSHOT_MATERIALIZATION cannot be set for index ‘%.*ls’ on ‘%.*ls’ because it is only applicable to indexes on views.
- 10643 – SNAPSHOT_MATERIALIZATION cannot be set for ‘%.*ls’ on ‘%.*ls’ because it is only applicable to clustered indexes on views.
- 10648 – SNAPSHOT_MATERIALIZATION cannot be set for partitioned index ‘%.*ls’ on ‘%.*ls’.
- 10649 – Nonclustered index ‘%.*ls’ cannot be created on ‘%.*ls’ that has clustered index ‘%.*ls’ with SNAPSHOT_MATERIALIZATION.
- 10650 – Refresh of snapshot view(s) requires snapshot isolation to be enabled on the database.
- 3760 – Cannot drop index ‘%.*ls’ on view ‘%.*ls’ that has SNAPSHOT_MATERIALIZATION.
- 4524 – Cannot alter view ‘%.*ls’ because it has snapshot materialization.
- 4525 – Cannot use hint ‘%ls’ on view ‘%.*ls’ that has snapshot materialization before the view is refreshed.
And new Extended Events:
So how can we create a snapshot-materialized view? (Microsoft hasn't documented it yet, obviously.) Here's a gist with things I've tried so far that haven't worked.
Best Answer
You can't. The feature is disabled in 2017 RTM.
That said, you can...
Using AdventureWorks:
Changes to the underlying tables are not immediately reflected in the view (as is normally the case with SQL Server). Likewise, data modifications against the underlying tables do not have to maintain the snapshot indexed view.
To refresh the view contents, one needs to call one of the new stored procedures:
This produces the execution plan:
This likely won't work for you, because either an undocumented trace flag is needed, or you need to do the particularly nasty thing I did: writing to the memory location holding the feature flag (using a debugger) to enable this feature.
If you're curious, the feature flag is the byte at
sqllang!g_featureSwitchesLangSvc+0x10f
. It is checked duringsqllang!SpRefreshSingleSnapshotView
.If you want to play along, and are fully prepared to accept the consequences of hacking about in SQL Server's code while it is running, and using a feature that Microsoft does not think is ready yet:
Set a breakpoint:
Resume SQL Server using the Go command (
g
)sys.sp_refresh_single_snapshot_view
command aboveWhen the breakpoint is hit, step through until you see the code line:
The offset may be different in other builds, for example in 2017 RTM CU3 it is
sqllang!g_featureSwitchesLangSvc+0x114
The memory address inside the parentheses may be different. Use the one you see.
Use the display memory command to see the current value at the memory address you found:
This should show a zero, indicating that the feature is disabled.
Change the zero to a one, using the enter values command (again with your memory address):
Disable the breakpoint and resume running SQL Server.
Note
SNAPSHOT_MATERIALIZATION
allows us to materialize a snapshot of a query specification that ordinarily could not be indexed, for example the below usesMAX
:Result: