用户定义的标量函数的 SQL*Server 常量值 - 性能

Posted

技术标签:

【中文标题】用户定义的标量函数的 SQL*Server 常量值 - 性能【英文标题】:SQL*Server Constant values for user defined scalar functions - performance 【发布时间】:2010-11-10 17:38:56 【问题描述】:

我有一个查询,当像这样运行时执行得非常好:

SELECT YADAYADA FROM MYTABLE WHERE FVAL <= 100 AND TVAL >= 100

由于存在 (FVAL,TVAL) 的索引,因此该查询作为非聚集索引查找整个查询是完全最优的。

现在,最好在此处使用从用户定义函数返回的常量。该函数将为整个交易返回一个常量值,而不仅仅是这个查询。但是这样做:

SELECT YADAYADA FROM MYTABLE WHERE FVAL <= dbo.myVal() AND TVAL >= dbo.myVal()

产生次优结果 - 查询计划不再作为索引搜索很好地运行,而是坚持搜索然后 过滤,这显然 MUCH 慢 - 即使在这种情况下,我的函数被定义为在这个非常简单的情况下返回一个常量值。

我尝试过使用 BETWEEN 子句 - 没有更好的方法。我试过表值函数,没有更好的(事实上,查询计划变得越来越复杂)。

有没有任何方法可以说服 SQL*Server '嘿,伙计,这是我们得到的 常量 值,并相应地优化计划?

【问题讨论】:

【参考方案1】:

最好的办法是在查询中声明一个变量,将 UDF 的值分配给该变量,然后在查询中使用该变量。

【讨论】:

我可以这样做 - 但最终这个 SQL 也隐藏在一个视图中(因此首先需要使用 UDF,它实际上是从 context_info 中提取的)......我不能在视图中放置一个 DECLARE。我可以将整个内容放在用户 TDF 或存储过程中 - 然后它将隐藏查询优化器中的所有其他列:-( 不幸的是,您似乎无法得到想要的东西。听起来您将不得不执行 UDF 将作为视图中的连接执行的任何查找。【参考方案2】:

SQL Server 试图变得聪明,并建议查询的值是什么,但有时开发人员知道得更好。

以下概念应该对您有所帮助

DECLARE @fval INT
DECLARE @tval INT
SET @fval = dbo.myVal()
SET @tval = dbo.myVal()

SELECT YADAYADA FROM MYTABLE WHERE FVAL <= @fval AND TVAL >= @tval
OPTION (OPTIMIZE FOR(@fval= 100, @tval = 100))

【讨论】:

以上是关于用户定义的标量函数的 SQL*Server 常量值 - 性能的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server用户定义的函数(UDF)使用详解

SQL Server 自定义函数(Function)——参数默认值

SQL Server 自定义函数

SQL Server 自定义函数

SQL Server 自定义函数(Function)——参数默认值

使用 EXECUTE 从 SQL Server 调用用户定义函数时的标量结果不同