Joh*_*ner 6 sql-server query hints temporal-tables
可能是一个非常简单的问题,但是FOR SYSTEM_TIME
在查询时态表时使用语句时,有没有办法为历史表指定查询/表提示?我怀疑不是,但我想在放弃这个之前仔细检查一下。
这是一个dbfiddle,它显示了我所知道的为查询指定提示的不同方式的基本细分,我能弄清楚如何传递与历史表交互的查询和/或表提示的唯一方法是转换查询到UNION ALL
live 和 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
子句并针对历史指定提示桌子?
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)
用。。。来代替 ''
使用 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)没有其他选择时才使用。
当使用参数化查询(通过设计或强制)时,计划指南的使用是最有益的,为每个临时查询可能性创建计划指南是不可行的。