Я получил доказательство того, что концепция работает. В моем случае iTVF был примерно в 3 раза быстрее с точки зрения как фактического времени, так и времени процессора. Не могу отблагодарить вас за ваш добрый и тщательный совет.
вопрос скорее гипотетический, чем реальная проблема кода. Но я представил упрощенную версию кода, чтобы проиллюстрировать этот вопрос. Пожалуйста, никаких комментариев о глупости самого кода. Фактический код слишком сложен (и запатентован), так что это лучший способ продолжить.
У меня есть скалярная функция следующим образом.
CREATE FUNCTION [dbo].[Compute_value]
(
@alpha FLOAT,
@bravo FLOAT,
@charle FLOAT,
@delta FLOAT
)
RETURNS FLOAT
AS
BEGIN
IF @alpha IS NULL OR @alpha = 0 OR @delta IS NULL OR @delta = 0
RETURN 0
IF @bravo IS NULL OR @bravo <= 0
RETURN 100
IF (@charle + @delta) / @bravo <= 0
RETURN 100
DECLARE @x = DATEDIFF(GETDATE(),'1/1/2000')
RETURN @alpha * POWER((100 / @delta), (-2 * POWER(@charle * @bravo, @x/365)))
END
Я слышал, что табличные функции обычно работают намного быстрее, чем скалярные, потому что они не RBAR. Поэтому я преобразовал логику для использования конструкции #temp_table просто для ее сравнения. Вместо примерно дюжины операторов IF у меня было бы такое же количество ОБНОВЛЕНИЙ, что и у #temp_table, и он выполнялся вдвое медленнее, чем скалярный UDF.
Я подумал, что, возможно, это происходит потому, что UDF может быстро вернуться при первых нескольких условиях, что приводит к тому, что большая часть скалярного UDF не работает, но это не так. Изучение планов выполнения запросов для решения #temp_table, похоже, указывает на то, что обновления вызывают большую часть стоимости плана.
Чего мне здесь не хватает? Если я преобразую это в функцию табличного значения, я застрял, делая обновления всей табличной переменной для каждого условного оператора? Есть ли способ избежать этого, который, кажется, значительно замедляет ход событий? Я что-то упускаю здесь очевидное?