Is there any way to modify the following UPDATE statement so that the scalar function is called only once, not twice?
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. Using the BETWEEN operator does not help – SQL Server calls the scalar function twice anyway.
This is often significantly more performant, but requires you to change the scalar function to an inline table valued function.
Although table valued functions return tables, you can choose to retun just one row with one field. Then you’re using it effectively as a scalar function – But, you get all the benefits of how SQL Server can optimise the query above…
– If the TVF is Inline (and not multi-statement)
– The TVF gets expanded out into the query
– The result is performance dramatiaclly better than scalar functions
Example Inline Table Valued Function:
Deliberately trivial
One example post about this: scalar-functions-inlining-and-performance
If you seach the web for
INLINE CROSS APPLY SCALAR FUNCTION PERFORMANCEI’m sure you’ll get a whole lot more.