使用 FOR SYSTEM_TIME 子句时历史表的查询/表提示

Joh*_*ner 6 sql-server query hints temporal-tables

可能是一个非常简单的问题,但是FOR SYSTEM_TIME在查询时态表时使用语句时,有没有办法为历史表指定查询/表提示?我怀疑不是,但我想在放弃这个之前仔细检查一下。

这是一个dbfiddle,它显示了我所知道的为查询指定提示的不同方式的基本细分,我能弄清楚如何传递与历史表交互的查询和/或表提示的唯一方法是转换查询到UNION ALLlive 和 history 表之间,而不是使用FOR SYSTEM_TIME子句。

在使用该FOR SYSTEM_TIME子句时尝试指定历史表提示时,出现以下错误:

Msg 308 Level 16 State 1 Line X
Index '<<HISTORY TABLE INDEX NAME>>' on table '<<LIVE TABLE NAME>>' (specified in the FROM clause) does not exist.
Run Code Online (Sandbox Code Playgroud)

在使用该FOR SYSTEM_TIME子句时尝试指定指向历史记录表的查询提示时,出现以下错误:

Msg 8723 Level 16 State 1 Line X
Cannot execute query. Object '<<HISTORY TABLE>>' 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.
Run Code Online (Sandbox Code Playgroud)

这些错误在表面上都是有意义的,因为查询中没有特别引用历史表,但是是否有另一个查询提示、跟踪标志等我可以使用,以便我仍然可以使用该FOR SYSTEM_TIME子句并针对历史指定提示桌子?

Ran*_*gen 5

虽然一般来说不是一个好主意,但似乎有效的解决方法是使用USE PLAN提示

从中获取 XML 的基本查询

-- 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'
Run Code Online (Sandbox Code Playgroud)

获取 XML 在此处输入图片说明

用。。。来代替 ''

在此处输入图片说明

使用 USE PLAN 和之前生成的执行计划运行查询

SELECT  *
FROM    dbo.People  FOR SYSTEM_TIME ALL 
WHERE   LEFT(VolatileData, 2) = '2A'
    AND Name = 'John' 
OPTION(USE PLAN N'...')
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明


使用计划指南强制执行计划

从基本查询更改'''''查询计划

在此处输入图片说明

创建计划指南

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'')'
Run Code Online (Sandbox Code Playgroud)

测试查询

SELECT  *
FROM    dbo.People  FOR SYSTEM_TIME ALL 
WHERE   LEFT(VolatileData, 2) = '2A'
    AND Name = 'John'
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明

使用计划指南,基于PlanGuideName计划的 XML 中的片段

PlanGuideName="TemplateGuide1" 
Run Code Online (Sandbox Code Playgroud)

&

UsePlan="true"
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,当我们添加几个空间时,不再使用计划指南

SELECT  *
FROM      dbo.People  FOR SYSTEM_TIME ALL 
WHERE   LEFT(VolatileData, 2) = '2A'
    AND Name = 'John'   
Run Code Online (Sandbox Code Playgroud)

导致查询没有索引提示

在此处输入图片说明

(在版本 14.0.3045.24 / SQL Server 2017 CU12 上测试)


笔记

虽然这是一种可能的解决方法,但仅在A)需要且B)没有其他选择时才使用。

当使用参数化查询(通过设计或强制)时,计划指南的使用是最有益的,为每个临时查询可能性创建计划指南是不可行的。