有没有办法修改以下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/