powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вызов UDF сильно тормозит
12 сообщений из 12, страница 1 из 1
Вызов UDF сильно тормозит
    #39844298
Alexey30
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день.
Есть простейшая функция для нахождения минимального значения из трех:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
CREATE FUNCTION [dbo].[InlineMin3Money](@val1 money, @val2 money, @val3 money)
RETURNS money
WITH SCHEMABINDING
AS
BEGIN
	
RETURN	Case When @Val1 < @Val2 And @Val1 < @Val3 Then @Val1
            When @Val2 < @Val1 And @Val2 < @Val3 Then @Val2 
            Else @Val3
            End

END



Возьмем тестовый скрипт:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
SET NOCOUNT ON 
SET STATISTICS TIME OFF

DECLARE @a TABLE(price1 MONEY, price2 MONEY, price3 MONEY)
DECLARE @i INT = 0

WHILE @i < 5000
BEGIN
	INSERT @a
		VALUES(1,2,3)

	SET  @i = @i + 1
END

SET STATISTICS TIME on

SELECT 
    dbo.InlineMin3Money(price1,price2,price3)
FROM @a



На нашем довольно шустром сервере он выполняется в среднем в район 50мс.

Если же заменяем вызов функции на выражение прямо в строке, то время выполнения снижается до 2-3мс.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
SET NOCOUNT ON 
SET STATISTICS TIME OFF

DECLARE @a TABLE(price1 MONEY, price2 MONEY, price3 MONEY)
DECLARE @i INT = 0

WHILE @i < 5000
BEGIN
	INSERT @a
		VALUES(1,2,3)

	SET  @i = @i + 1
END

SET STATISTICS TIME on

SELECT 
    	Case When price1 < price2 And price1 < price3 Then price1
				When price2 < price1 And price2 < price3 Then price2 
				Else price3
				END
FROM @a



То есть всё тоже самое, только без вызова функции.
Подскажите, пожалуйста, как сделать её вызов более быстрым? В реальном запросе выражения более громоздкие, поэтому их пихать напрямую без функции неудобно.
Спасибо.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844299
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30Подскажите, пожалуйста, как сделать её вызов более быстрым?Сделать функцию инлайновой
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
CREATE FUNCTION [dbo].[InlineMin3Money](@val1 money, @val2 money, @val3 money)
RETURNS table
AS
return	
 select	Case When @Val1 < @Val2 And @Val1 < @Val3 Then @Val1
            When @Val2 < @Val1 And @Val2 < @Val3 Then @Val2 
            Else @Val3
        End as min_val
go

DECLARE @a TABLE(price1 MONEY, price2 MONEY, price3 MONEY)
DECLARE @i INT = 0

WHILE @i < 5000
BEGIN
	INSERT @a
		VALUES(1,2,3)

	SET  @i = @i + 1
END

SET STATISTICS TIME on

SELECT 
 *
FROM @a a cross apply
dbo.InlineMin3Money(price1, price2, price3) b



Ну или дождаться 2019-го сервера.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844302
Alexey30
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо за ответ.
Cross Apply в примере использовать удобно, а в реальном запросе особо не вариант.
Неужели нет никакого более "красивого" метода?
Microsoft SQL Server 2016 (SP2-GDR)
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844309
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Установить сервер, в котором есть инлайновые скалярки.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844314
Alexey30
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гавриленко Сергей Алексеевич, печально.
CLR можно не пробовать?
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844322
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30,

как раз подходящий случай для CLR функции.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844324
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30Cross Apply в примере использовать удобно, а в реальном запросе особо не вариант.А почему?
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844340
Alexey30
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, запрос читается сложнее, на мой взгляд. Странно запихивать во FROM то, что должно быть в SELECT.
Однако действительно работает довольно шустро, изменил только тело функции на такое:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
ALTER FUNCTION [dbo].[InlineMin3MoneyInline](@val1 money, @val2 money, @val3 money)
RETURNS table
AS
return	
 select	MIN(val) min_val
 FROM (
	VALUES(@val1), (@val2), (@val3)) a(val)
go
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844341
Alexey30
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alexey30, При этом производительность чуть-чуть хуже, чем в первоначальном варианте функции, но там отсутствовали проверки на NULL.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844346
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30,

разница принципиальная.
В первом случае сервер будет вычислять выражение для каждого значения атрибута, а во втором выполнит "подзапрос", который сможет встроить в план запроса так, как если бы обращение происходило к таблице.

Соответственно, первый вариант не сможет использовать параллельный план выполнения, как минимум.
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844358
Фотография vikkiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30..Cross Apply в примере использовать удобно, а в реальном запросе особо не вариант.
Неужели нет никакого более "красивого" метода?..насколько помню cross apply будет для каждой строки, одна за одной, по очереди, впрочем как и функция на строку
т.е. по любому последовательное выполнение без паралельности
единственная паралельность как указали выше - в пределах одной строки по значениям под-таблицы,
т.е. как-бы лучше - но и не сильно

для полной паралельности - можно попробовать табличную CLR,
и там уже внутри выстраивать многопоточный алгоритм
...
Рейтинг: 0 / 0
Вызов UDF сильно тормозит
    #39844447
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexey30Спасибо за ответ.
Cross Apply в примере использовать удобно, а в реальном запросе особо не вариант.
Неужели нет никакого более "красивого" метода?
Microsoft SQL Server 2016 (SP2-GDR)

Функции - зло ;-)

Сделайте запрос с раскрученным запросом в процедуре
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вызов UDF сильно тормозит
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]