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 在这里非常敏感。也就是说,除非您每分钟运行一百万次执行,或者您的硬件规模非常小,否则开销是极其不存在的。
您可能还想使用 OPTION RECOMPILE - 因为您的另一个问题是 SQL Server 重用查询计划。这里的查询计划可能取决于 id 表的大小 - 因此,如果不同的大小导致不同的结果并且无论如何都会重用相同的计划,则提示将不起作用。
实际上,我会假设 50 行的查询计划是一个很好的折衷方案,会使用表变量,并且如果需要的话,可以选择重新编译。