patternsqlMinor
Query/Table Hints for the History Table when Using the FOR SYSTEM_TIME Clause
Viewed 0 times
thehistoryquerysystem_timehintsforusingwhenclausetable
Problem
Probably a pretty quick question, but is there any way to specify Query/Table hints for the History Table when using the
Here's a dbfiddle that shows a basic breakdown of different ways I'm aware of specifying hints for a query, and the only way I can figure out how to pass query and/or table hints that interact with a history table is to convert the query to a
When trying to specify a history table hint when using the
When trying to specify a query hint pointing to the history table when using the
These errors both make sense on the surface as the history table is not specifically referenced in the query, but is there another query hint, trace flag, etc. that I can use so that I can still use the
FOR SYSTEM_TIME statement when querying temporal tables? I suspect not, but I wanted to double-check before I throw in the towel on this one.Here's a dbfiddle that shows a basic breakdown of different ways I'm aware of specifying hints for a query, and the only way I can figure out how to pass query and/or table hints that interact with a history table is to convert the query to a
UNION ALL between the live and history tables rather than use the FOR SYSTEM_TIME clause.When trying to specify a history table hint when using the
FOR SYSTEM_TIME clause, I get the following error:Msg 308 Level 16 State 1 Line X
Index '>' on table '>' (specified in the FROM clause) does not exist.When trying to specify a query hint pointing to the history table when using the
FOR SYSTEM_TIME clause, I get the following error:Msg 8723 Level 16 State 1 Line X
Cannot execute query. Object '>' is specified in the TABLE HINT clause, but is not used in the query or does not match the alias specified in the query. Table references in the TABLE HINT clause must match the WITH clause.These errors both make sense on the surface as the history table is not specifically referenced in the query, but is there another query hint, trace flag, etc. that I can use so that I can still use the
FOR SYSTEM_TIME clause and specify hints against the history table?Solution
While not a great idea in general, a workaround that seems to work is using the
Base query to get the XML from
Get the XML
Replace ' with ''
Run the query with USE PLAN and the previously generated execution plan
Result
Using a plan guide to force the plan
Change
Create the plan guide
Test the query
Result
The plan guide is used, based on the
&
As expected, when we add a couple of spaces the plan guide is no longer used
Resulting in the query without the index hints
(Tested on build version 14.0.3045.24 / SQL Server 2017 CU12)
Notes
While this is a possible workaround it is only meant to be used if it is A) needed and B) there are no other options.
The use of plan guides is most beneficial when using paramaterized queries (either by design or force), creating a plan guide for each ad hoc query possibility is not feasible.
USE PLAN hintBase query to get the XML from
-- UNION ALL instead of FOR SYSTEM_TIME clause - Table Hints
SELECT *
FROM dbo.People WITH (INDEX(IX_Live_People__Name))
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'
UNION ALL
SELECT *
FROM hist.People WITH (INDEX (IX_Hist_People__Name))
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'Get the XML
Replace ' with ''
Run the query with USE PLAN and the previously generated execution plan
SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'
OPTION(USE PLAN N'...')Result
Using a plan guide to force the plan
Change
' to '''' in the query plan from the base queryCreate the plan guide
EXEC sp_create_plan_guide
@name = N'TemplateGuide1',
@stmt = N'SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = ''2A''
AND Name = ''John''',
@type = N'SQL',
@module_or_batch = NULL,
@hints = N'OPTION(USE PLAN N''Plan Here'')'Test the query
SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'Result
The plan guide is used, based on the
PlanGuideName fragment in the plan's XMLPlanGuideName="TemplateGuide1"&
UsePlan="true"As expected, when we add a couple of spaces the plan guide is no longer used
SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'Resulting in the query without the index hints
(Tested on build version 14.0.3045.24 / SQL Server 2017 CU12)
Notes
While this is a possible workaround it is only meant to be used if it is A) needed and B) there are no other options.
The use of plan guides is most beneficial when using paramaterized queries (either by design or force), creating a plan guide for each ad hoc query possibility is not feasible.
Code Snippets
-- UNION ALL instead of FOR SYSTEM_TIME clause - Table Hints
SELECT *
FROM dbo.People WITH (INDEX(IX_Live_People__Name))
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'
UNION ALL
SELECT *
FROM hist.People WITH (INDEX (IX_Hist_People__Name))
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'
OPTION(USE PLAN N'...')EXEC sp_create_plan_guide
@name = N'TemplateGuide1',
@stmt = N'SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = ''2A''
AND Name = ''John''',
@type = N'SQL',
@module_or_batch = NULL,
@hints = N'OPTION(USE PLAN N''Plan Here'')'SELECT *
FROM dbo.People FOR SYSTEM_TIME ALL
WHERE LEFT(VolatileData, 2) = '2A'
AND Name = 'John'PlanGuideName="TemplateGuide1"Context
StackExchange Database Administrators Q#238721, answer score: 5
Revisions (0)
No revisions yet.