【问题标题】:SQL*Server Constant values for user defined scalar functions - performance用户定义的标量函数的 SQL*Server 常量值 - 性能
【发布时间】: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 '嘿,伙计,这是我们得到的 常量 值,并相应地优化计划?

【问题讨论】:

    标签: sql sql-server performance tsql


    【解决方案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))
    

    【讨论】:

      猜你喜欢
      • 2011-05-18
      • 2016-02-18
      • 2023-04-09
      • 1970-01-01
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 2019-06-10
      相关资源
      最近更新 更多