用户定义的标量函数的 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 自定义函数(Function)——参数默认值