我正在做一個相對複雜的CTE查詢與昂貴的用戶定義的標量函數調用。嵌套選擇內昂貴的函數
CTE的where子句過濾大部分大表數據,並返回相對較小的結果,因此如果計算結果集,計算昂貴的字段不是問題。
如果不評估昂貴的列,如果沒有被CTE子查詢中的任何謂詞所觸及,SQL服務器就會很好地工作,它僅對結果集進行評估。
問題是,在這種情況下,我可以依賴優化程序的這種優良行爲,還是在計劃重建時可能出錯?
這是一個測試代碼。
use tempdb;
go
/****** Object: UserDefinedFunction [dbo].[expensive] Script Date: 01/15/2010 18:43:06 ******/
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.
-- inexpensive in case of @i = 1
create function dbo.expensive(@i int)
returns int
as
begin
if(@i = 1) begin return @i; -- inexpensive in this case
end;
declare @N bigint
declare @ret bigint
set @N = 17; -- will generate a set of 2^N
declare @tab table(num int);
with gig as
(
select 1 as num
union all
select g.num + 1 as num from gig g
where g.num < @N
union all
select g.num + 1 as num from gig g
where g.num < @N
)
select @ret = count(num) from gig;
return @ret;
end
go
declare @tab table(i int);
insert into @tab select 1 union select 2 union select 3;
select CURRENT_TIMESTAMP;
with source as
(
-- some really complex stuff that has an expensive calcutated scalar
select c.i, c.caclulated from @tab t
join
(select i, dbo.expensive(i) as caclulated from @tab) as c
on t.i = c.i
)
select * from source where
i = 1; -- this query is inexpensive, because do not touch anything but 1
select CURRENT_TIMESTAMP;
-- this one is expensive
select dbo.expensive(2)
select CURRENT_TIMESTAMP;
我在收集你給出的CTE是一個例子,而不是你真正使用的。你會對真正的CTE以及它的工作方式有所瞭解嗎?你可以發佈代碼嗎?你真的想要解決什麼問題?我可以回答執行計劃,但我懷疑可能有其他答案可以幫助你。 – ErikE 2010-01-16 19:42:24