将表提示与变量 table 一起使用

Use table hints with variable table

提问人:clickit 提问时间:5/31/2023 最后编辑:clickit 更新时间:5/31/2023 访问量:93

问:

我有这个变量表

declare @mapping table (
    the_row int
    , Company smallint
    , Branch smallint 
    , Flag bit 
      index aa clustered (Company, Branch)
    , index bb nonclustered (Flag)
)

看来我不能使用这样的表格提示

select *
from @mapping mapping with(index=[aa])

select *
from @mapping mapping with(index=[bb])

它抱怨

关键字“with”附近的语法不正确。如果此语句是公用表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则必须用分号终止上一个语句。

根据用例使用不同索引的另一种方法吗?

sql-server t-sql 变量 query-hints

评论

1赞 Dale K 5/31/2023
这是一个有趣的问题,尽管实际上如果有足够的数据表明索引会有所帮助,但我认为使用临时表会更好,我认为它会表现得更好。
0赞 Dale K 5/31/2023
顺便说一句,在你的第一个索引定义之前有一个逗号吗?
2赞 Dale K 5/31/2023
官方文档表明,无法为表变量指定索引。
2赞 Nick.Mc 5/31/2023
回应答案和评论:如果表变量的性能问题,第一步是移动到临时表。如果有任何性能问题,最后一步是使用索引提示。
1赞 Charlieface 5/31/2023
同意,你可能应该调查一下为什么你认为你首先需要提示,如果没有更好的选择,很少需要

答:

3赞 gotqn 5/31/2023 #1

不允许对表变量使用索引表提示。在官方文档中,信息具有误导性:

enter image description here

因为它没有指定哪种类型的表支持它。可以在这篇比较 @table 和 #temp 表的精彩文章中找到一瞥。

通常,表变量适用于少量数据。因此,如果您正在处理数千行,最好阅读有关性能差异的信息。

此外,使用表格提示应该很少见。大多数时候,引擎足够智能,可以决定使用哪个索引。

评论

0赞 Dale K 5/31/2023
我在评论中引用的文档似乎确实在说这是不可能的
0赞 gotqn 5/31/2023
@DaleK我仍然找不到它。你能分享到特定部分的链接吗?
2赞 Dale K 5/31/2023
@gotqn事实是,只有后面跟着一个选项,后面没有那个选项。table_or_view_namewith@variable
0赞 Lemonina 5/31/2023 #2

表提示,例如不允许在表变量上使用WITH (INDEX = ...)

  • 优化器包含有关表变量的所有信息(# 行 | 结构...) - 无需提示任何特定索引

您可以使用查询设计来控制索引使用情况

  • 如果你想让优化器使用聚簇索引(公司、分支)——你可能想写
SELECT *
FROM @mapping
WHERE Company = @Company AND Branch = @Branch;
  • 如果要在 Flag 上使用非聚集索引,请尝试筛选该列
SELECT *
FROM @mapping
WHERE Flag = @Flag;
  • 如果索引提示对您的情况很重要 - 请考虑临时表而不是表变量
CREATE TABLE #mapping (
    the_row int
    , Company smallint
    , Branch smallint 
    , Flag bit 
);

CREATE CLUSTERED INDEX aa ON #mapping (Company, Branch);
CREATE NONCLUSTERED INDEX bb ON #mapping (Flag);