sql - 避免在 UPDATE 语句中多次调用标量函数

标签 sql sql-server tsql

有没有办法修改以下UPDATE语句,以便标量函数仅被调用一次,而不是两次?

UPDATE a
    SET SomeField = b.SomeField
    FROM TableA AS a
    JOIN TableB b ON b.Link = a.Link
    WHERE b.CostMin <= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)
        AND b.CostMax >= @Cost * dbo.OneScalarFunction(@CurrencyFrom, b.Currency)

P.S.使用 BETWEEN 运算符没有帮助 - SQL Server 无论如何都会调用标量函数两次。

最佳答案

这通常会显着提高性能,但需要您将标量函数更改为内联表值函数。

UPDATE
  a
SET
  SomeField = b.SomeField
FROM
  TableA AS a
CROSS APPLY
  dbo.oneInlineTableValuedFunction(@CurrencyFrom, e.Currency) AS ITVF
INNER JOIN
  TableB b
    ON b.Link = a.Link
WHERE
      b.CostMin <= @Cost * ITVF.exchangeRate
  AND b.CostMax >= @Cost * ITVF.exchangeRate

虽然表值函数返回表,但您可以选择仅重新调整具有一个字段的一行。然后,您可以有效地将其用作标量函数 - 但是,您可以获得 SQL Server 如何优化上述查询的所有好处...
- 如果 TVF 是内联(而不是多语句)
- TVF 扩展到查询中
- 结果是性能明显优于标量函数


内联表值函数示例:

CREATE FUNCTION dbo.oneInlineTableValuedFunction (
                      @currencyFrom   VARCHAR(32),
                      @currencyTo     VARCHAR(32)
)
RETURNS TABLE
AS
RETURN (
  SELECT
    exchangeRate
  FROM
    dbo.someTable
  WHERE
        currencyFrom = @currencyFrom
    AND currencyTo   = @currencyTo
)

故意琐碎

关于此的一个示例帖子:scalar-functions-inlining-and-performance

如果您在网上搜索内联交叉应用标量函数性能,我相信您会得到更多信息。

关于sql - 避免在 UPDATE 语句中多次调用标量函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13379057/

相关文章:

sql - 层次问题

sql-server - SQL Replace 函数中的正则表达式模式?

c# - DataTable.Load() 时应用程序中断,问题在哪里?

sql-server - BCP 到 .csv 分隔符问题

sql-server - 从 VBA 执行 SQL Server 存储过程并检索所有消息和结果集

sql - 使用 JOIN 关键字时添加两个条件是一个好习惯吗?

sql - 接收语法错误: line 1:126 missing EOF at 'LIMIT' (… WHERE language = uk; [LIMIT] 200)

sql - 在每个句子之前打印项目符号 + 在每个句子之后换行 SQL

sql - 按包含空值的列排序?

MySQL 多表子查询