1

我有一个相对复杂的查询,有几个自连接,适用于一个相当大的表。为了使该查询更快地执行,我只需要处理数据的一个子集。根据传递的参数,所述数据子集的范围可以在 12 000 到 120 000 行之间。

可以在此处找到更多详细信息:SQL Server CTE 在自连接中引用缓慢

如您所见,我之前使用 CTE 返回数据子集,这导致了一些性能问题,因为 SQL Server 为每个连接重新运行 CTE 中的 Select 语句,而不是简单地运行一次并重用其数据集。

另一种方法是使用临时表工作得更快(同时在 UDF 主体之外的单独窗口中测试查询)。但是,当我尝试在多语句 UDF 中实现这一点时,SQL Server 严厉提醒我,由于某种原因,多语句 UDF 不支持临时表......

但是,UDF 确实允许表变量,所以我尝试了,但性能非常糟糕,因为我的查询需要 1 分 40 秒才能完成,而 CTE 版本需要 40 秒。我认为由于此线程中列出的原因,表变量很慢:SQL Server 存储过程中插入时表变量性能不佳

临时表版本大约需要 1 秒,但由于 SQL Server 的限制,我无法将其转换为函数,我必须将表返回给调用者。

考虑到 CTE 和表变量都太慢,并且临时表在 UDF 中被拒绝,为了让我的 UDF 快速执行,我有哪些选择?

提前非常感谢。

4

3 回答 3

3

在许多这样的情况下,我们需要做的就是为这些表变量声明主键,它又快了。

于 2010-06-16T18:41:53.927 回答
1

设置和使用Process-Keyed Table,请参阅文章:来自 Erland Sommarskog 的如何在存储过程之间共享数据

于 2010-06-16T18:42:04.073 回答
0

我使用过的一个笨拙的解决方法涉及这样的代码(如下是伪代码):

CREATE TEMP TABLE #foo

EXECUTE MyStoredProcedure

SELECT *
 from #foo

GO

--  Stored procedure definition
CREATE PROCEDURE MyStoredProcedure
AS

INSERT #foo values (whatever)

RETURN
GO

简而言之,存储过程引用并使用由调用过程(或例程)创建的临时表。这会起作用,但如果您没有清楚地记录它,其他人可能会混淆正在发生的事情,并且您将获得重新编译、统计重新计算和其他可能消耗不需要的时钟周期的奇怪现象。

于 2010-06-16T18:25:20.207 回答