【发布时间】:2010-06-22 16:04:26
【问题描述】:
我有一个需要很长时间才能执行的 SQL 请求。所以我想让它变得更好,但不知道如何去做。 这是一个例子: 我的要求:
SELECT * from T1
Inner join T2 on T1.a = T2.b
Inner join T3 on T2.c = T3.d
WHERE 1=1
AND T2.e = 'a certain value' --I call i the Clause1
and dbo.MyUDF(T1.id) = 1 --I call i the Clause2
问题似乎来自 UDF 调用。 在没有 Clause1 和 Clause2 的情况下运行请求将给我 2500 行,需要 7 秒。
在没有 Clause2 的情况下运行请求将给我 16 行需要 9 秒。
使用所有 2 个子句运行请求将为我提供 15 行,耗时 1:45 分钟。
但在游标中调用 MyUdf 16X 需要 9 秒。
declare curs cursor
for SELECT T1.id from T1
Inner join T2 on T1.a = T2.b
Inner join T3 on T2.c = T3.d
WHERE 1=1
AND T2.e = 'a certain value'
open curs
fetch next from curs into @fid
while(@@FETCH_STATUS = 0)
BEGIN
select dbo.MyUdf(@fid)
fetch next from curs into @fid
END
close curs
deallocate curs
因此,de SQL 引擎似乎使用 UDF 和运行子句 1 测试了所有 2500 行。而且我希望它做另一个,这样 UDF 将只在 16 行上被调用。
有什么想法吗?
--编辑-- 看一下执行计划,它告诉我我的 UDF 不会使用很多 mutch。所以我认为它总是把它放在第一位。所以我需要告诉 sql server 这部分请求是最糟糕的,它必须在最后一步接受它。你知道怎么做吗?
【问题讨论】:
-
为什么你的所有查询中都有
1=1? -
你想从 UDF 返回什么?
-
你需要发布
dbo.MyUDF的内容。 SQL 是基于集合的;模块化/OO 编程概念(通常)不适用。 -
Ben S:我在每个查询中得到 1=1,因为查询是由引擎生成的,而且这是不检查是否已经存在条件的简单方法。
-
UDF 用于过滤结果。它包含每个项目的保密规则。它有时会使用相同的 UDF 进行递归。
标签: sql sql-server