Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / производительность UDF / 11 сообщений из 11, страница 1 из 1
03.07.2002, 18:24:59
    #32035001
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
Привет всем

У меня возникла проблема с производительностью 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
03.07.2002, 18:35:12
    #32035002
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
прошу прощения, код должен выглядеть так:
Код: 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
03.07.2002, 18:56:57
    #32035009
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
У меня планы выполнения и стоимости запросов АБСОЛЮТНО одинаковы.

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

SQL2000EE+SP2, Win2000AS+SP2
...
Рейтинг: 0 / 0
03.07.2002, 19:16:27
    #32035015
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
вот так видно все невооруженным глазом.
Код: 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
03.07.2002, 19:29:02
    #32035018
guest
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
Да планы запросов одинаковые. Но если посмотреть в Profiler будет видно, что функция dbo.fn_tmp() выполняется для каждой строки результирующего набора.
...
Рейтинг: 0 / 0
03.07.2002, 19:50:47
    #32035019
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
Guest прав - пользовательская функция вызывается для каждой строки, поэтому сранивать ее с GETDATE(), которая вычисляется точно один раз некорректно.

Посранивайте лучше с ну хотя бы с
master.dbo.fn_varbintohexsubstring()
...
Рейтинг: 0 / 0
03.07.2002, 20:03:34
    #32035021
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
т.е. это свойство скалярной UDF. и вычислить значение 1 раз на запрос никак нельзя?
тогда совсем непонятно, зачем запрещать вызов не-deterministic функций из UDF.
странно, ничего подобного не нашел в боле и интернете
везде грабли :(
...
Рейтинг: 0 / 0
03.07.2002, 20:24:51
    #32035022
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
чудеса!
Код: 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
04.07.2002, 10:18:01
    #32035095
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
ну всё правильно - теперь это же работает как фильтр
...
Рейтинг: 0 / 0
04.07.2002, 13:24:26
    #32035147
Miha
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
производительность UDF
в последнем примере я ошибся, профайлер показал вызов функции для каждой строки 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
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / производительность UDF / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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