【问题标题】:Expensive function inside a nested select嵌套选择中的昂贵函数
【发布时间】:2010-01-15 16:11:49
【问题描述】:

我正在使用昂贵的用户定义标量函数调用进行相对复杂的 CTE 查询。

CTE 的 where 子句过滤了大部分大表数据,返回的结果相对较小,所以如果在结果集上计算,计算昂贵的字段是没有问题的。

如果不评估昂贵的列,SQL 服务器会做得很好,如果 CTE 子查询中的任何谓词都没有触及它,那么它只会针对结果集进行评估。

问题是,在这种情况下,我是否可以依赖优化器的这种良好行为,或者重建计划时可能会出现问题?

这是一个测试代码。

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 及其工作原理?你可以发布它的代码吗?你真正想解决什么问题?我可以回答有关执行计划的问题,但我怀疑可能还有其他答案会对您有所帮助。

标签: sql-server query-optimization


【解决方案1】:

你永远不会知道。您可以做的一件事是使用计划指南来帮助优化器保持正确的路径。见Optimizing Queries in Deployed Applications by Using Plan Guides

【讨论】:

  • 能否请您直接查看有关此问题的 msdn 文档部分?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 2018-03-08
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
相关资源
最近更新 更多