0

SQL Server 2008 でユーザー定義関数の決定論的な動作に基づいて最適化を達成しようとしています。

私のテストコードでは、決定論的で同じ引数値で呼び出されるため、追加の関数呼び出し dbo.expensive はないと予想しています。

私のコンセプトが機能しません。理由を説明してください。期待される最適化を達成するために何ができるでしょうか?

use tempdb;
go
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[expensive]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[expensive]

go
-- used to model expensive user defined function.
-- expecting to take about 1 second to execute
create function dbo.expensive(@i int)
returns int with schemabinding
as
begin
 declare @N bigint
 declare @ret bigint
 set @N = 16; -- will generate a set of 2^N
 declare @tab table(num int);

 with multiplicity as
 (
  select 1 as num
  union all
  select m.num + 1 as num from multiplicity m
  where m.num < @N
  union all
  select m.num + 1 as num from multiplicity m
  where m.num < @N
 )
 select @ret = count(num) + @i from multiplicity;
 return @ret;
end

go

declare @tab table(x int);

with manyItems as
(
 select 1 as iterator
 union all
 select iterator + 1 from manyItems
 where iterator < 5
)
insert into @tab select 1 from manyItems;

select CURRENT_TIMESTAMP;
-- expected to take about 1 second
select dbo.expensive(1)

select CURRENT_TIMESTAMP;

-- i want to make this one execute in 1 second too
select x, dbo.expensive(x) as y from @tab;

select CURRENT_TIMESTAMP;

SELECT OBJECTPROPERTY(OBJECT_ID('dbo.expensive'), 'IsDeterministic');
4

1 に答える 1

1

可能であれば、関数をインラインのテーブル値 UDF に変換します ( http://msdn.microsoft.com/en-us/library/ms189294.aspx )。

例えば

create function dbo.expensive2(@N bigint, @i int)
returns table with schemabinding
as
 return
 with multiplicity as
 (
  select 1 as num
  union all
  select m.num + 1 as num from multiplicity m
  where m.num < @N
  union all
  select m.num + 1 as num from multiplicity m
  where m.num < @N
 )
 select count(num) + @i as ret from multiplicity

そして、次のように呼び出します。

select x, (select ret from dbo.expensive2(16, x)) as y from @tab;
于 2010-02-09T17:35:25.243 に答える