SQL Server 中有针对行数的优化器提示吗?

问题描述 投票:0回答:1

SQL Server 中是否有针对行数的优化器提示? 在我们的应用程序中,我们经常遇到需要将查询限制为一大组 id 的情况。如果我们通过内子句执行此操作,我们会从大约 1000 个集合中遇到很大的性能问题。为了解决这个问题,我们使用 STRING_SPLIT 函数,该函数通常效果很好。

select * 
from (complex query) as foo 
join  string_split(@ids, ';') as ids 
  on foo.id = ids.value

参数@ids是我们的应用程序传递的。

但对于某些查询,我们会再次遇到性能问题,因为优化器总是估计此函数返回的行数值为 50。因此,我们首先将 STRING_SPLITT 函数的返回值写入临时表并在查询中使用它。为此,优化器可以很好地估计行数。

select value as id into #ids
from string_split(@ids, ';')

select * 
from (complex query) as foo 
join  #ids as ids 
  on foo.id = ids.value

但是,在我们的应用程序中创建查询时,我们确切地知道行数。有什么方法可以将其作为提示传递给优化器吗?然后我们可以使用临时表节省所有开销。

我找到了一种方法让优化器估计少于 50 行(带有 TOP),但没有一种方法可以增加估计值。

sql-server optimization hint
1个回答
0
投票

不。好吧,不知道。

您可以告诉它针对快速的第一个数据进行优化(即使用较慢的查询,如果它更快地返回第一个数据)并告诉它您想要多少行(顶部),但仅此而已。

说真的,你的问题看起来像是糟糕的编程。这并不是很明显 - SQL Server 在这里非常敏感。也就是说,除非您每分钟运行一百万次执行,或者您的硬件规模非常小,否则开销是极其不存在的。

  • 您可以使用表VARIABLE来保存数据,并带有索引。不需要临时表。它在技术上非常相似,但具有不同的语义含义(例如变量的范围与临时表的生命周期不同)。变量上的索引,事后执行...

您可能还想使用 OPTION RECOMPILE - 因为您的另一个问题是 SQL Server 重用查询计划。这里的查询计划可能取决于 id 表的大小 - 因此,如果不同的大小导致不同的结果并且无论如何都会重用相同的计划,则提示将不起作用。

实际上,我会假设 50 行的查询计划是一个很好的折衷方案,会使用表变量,并且如果需要的话,可以选择重新编译。

© www.soinside.com 2019 - 2024. All rights reserved.