powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / производительность UDF
11 сообщений из 11, страница 1 из 1
производительность UDF
    #32035001
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет всем

У меня возникла проблема с производительностью UDF.
В следующум простейшем примере фукция принимает константные аргументы, и по идее, должна вызываться 1 раз. Однако, время выполнения запросов говорит об обратном.
Смотрел планы выполнения - идентичны.
В чем дело? Сколько раз вызывается UDF?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
use tempdb
go
create table t1( k int primary key clustered, v int )
go
insert into t1 (k, v) values ( 1 ,  100 )
go
create function fn_tmp( @k int ) returns int
as
begin
	return (select v from t1 where k = @k)
end
go

 -- почувствуйте разницу между этим:
 
select count(dbo.fn_tmp( 1 )) from sysobjects s1, sysobjects s2, sysobjects s3
 -- и этим:
 
select count(getdate()) from sysobjects s1, sysobjects s2, sysobjects s3
go

drop function fn_tmp
go
drop table t1
go
...
Рейтинг: 0 / 0
производительность UDF
    #32035002
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
прошу прощения, код должен выглядеть так:
Код: plaintext
1.
2.
3.
select dbo.fn_tmp( 1 ) from sysobjects s1, sysobjects s2, sysobjects s3

select getdate() from sysobjects s1, sysobjects s2, sysobjects s3
...
Рейтинг: 0 / 0
производительность UDF
    #32035009
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня планы выполнения и стоимости запросов АБСОЛЮТНО одинаковы.

SQL2000EE SP2, Win2000 AdvServ SP2
...
Рейтинг: 0 / 0
производительность UDF
    #32035012
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2 Glory:
у меня тоже, но время выполнения различается в разы.
К тому же, время сильно зависит от величины выборки.

SQL2000EE+SP2, Win2000AS+SP2
...
Рейтинг: 0 / 0
производительность UDF
    #32035015
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вот так видно все невооруженным глазом.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
declare @dt datetime
declare @dt1 datetime
declare @a int
set @dt = getdate()
select dbo.fn_tmp( 1 ) from sysobjects s1, sysobjects s2, sysobjects s3
set @dt1 = getdate()
print datediff(ms, @dt, @dt1)

set @dt = getdate()
select getdate() from sysobjects s1, sysobjects s2, sysobjects s3
set @a = dbo.fn_tmp( 1 )  -- даже вызовем функцию
 
set @dt1 = getdate()
print datediff(ms, @dt, @dt1)
go

мои результаты:
810
180
...
Рейтинг: 0 / 0
производительность UDF
    #32035018
guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да планы запросов одинаковые. Но если посмотреть в Profiler будет видно, что функция dbo.fn_tmp() выполняется для каждой строки результирующего набора.
...
Рейтинг: 0 / 0
производительность UDF
    #32035019
Glory
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Guest прав - пользовательская функция вызывается для каждой строки, поэтому сранивать ее с GETDATE(), которая вычисляется точно один раз некорректно.

Посранивайте лучше с ну хотя бы с
master.dbo.fn_varbintohexsubstring()
...
Рейтинг: 0 / 0
производительность UDF
    #32035021
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.е. это свойство скалярной UDF. и вычислить значение 1 раз на запрос никак нельзя?
тогда совсем непонятно, зачем запрещать вызов не-deterministic функций из UDF.
странно, ничего подобного не нашел в боле и интернете
везде грабли :(
...
Рейтинг: 0 / 0
производительность UDF
    #32035022
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чудеса!
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
declare @dt datetime
declare @dt1 datetime
set @dt = getdate()
select  100  from sysobjects s1, sysobjects s2, sysobjects s3 where dbo.fn_tmp( 1 ) != s1.id
set @dt1 = getdate()
print datediff(ms, @dt, @dt1)
go
declare @dt datetime
declare @dt1 datetime
set @dt = getdate()
select  100  from sysobjects s1, sysobjects s2, sysobjects s3
set @dt1 = getdate()
print datediff(ms, @dt, @dt1)
go

результат:
70
70

в where мы вычисляемся 1 раз! оччень логично...
...
Рейтинг: 0 / 0
производительность UDF
    #32035095
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну всё правильно - теперь это же работает как фильтр
...
Рейтинг: 0 / 0
производительность UDF
    #32035147
Miha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
в последнем примере я ошибся, профайлер показал вызов функции для каждой строки sysobjects s1.
Значит, UDF вызывается столько раз, сколько сервер вычисляет все выражение, и это не зависит от аргументов функции.
для примера:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 --вызывается 1 раз, в плане: where(STARTUP EXPR:(dbo.fn_tmp(1) = 100))
 
 --т.к. сравнивается с константой
 
select  100  from sysobjects s1, sysobjects s2, sysobjects s3 where dbo.fn_tmp( 1 ) =  100 

 --вызывается count(sysobjects) раз для каждой строки из s1
 
select  100  from sysobjects s1, sysobjects s2, sysobjects s3 where dbo.fn_tmp( 1 ) != s1.id


что интересно, следующий пример тоже дает несколько обращений к функции:

Код: plaintext
1.
2.
3.
4.
5.
select  100  from 
	((sysobjects s1 inner join sysobjects s2 on s1.id != s2.id)
	inner join sysobjects s3 on s3.id != s1.id)
	inner join
	(select dbo.fn_tmp( 1 ) as f) v on v.f != s1.id


только так удалось добиться одного вызова с помощью явно заданного плана запроса:
Код: plaintext
1.
2.
3.
4.
5.
select  100  from 
	((sysobjects s1 inner loop join sysobjects s2 on s1.id != s2.id)
	inner loop join sysobjects s3 on s3.id != s1.id)
	inner loop join
	(select dbo.fn_tmp( 1 ) as f) v on v.f != s1.id


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


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