SQL Server多语句UDF-临时需要的数据存储方式

发布于 2024-09-06 02:20:34 字数 909 浏览 5 评论 0原文

我有一个相对复杂的查询,有几个自连接,适用于相当大的表。 为了使该查询执行得更快,我只需要使用数据的子集。 取决于传递的参数,所述数据子集的范围可以在12000行和120000行之间。

更多详细信息可以在这里找到:自连接中引用的 SQL Server CTE 速度慢< /a>

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

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

但是 UDF 确实允许表变量,所以我尝试了这一点,但性能绝对糟糕,因为我的查询需要 1 分 40 秒才能完成,而 CTE 版本需要 40 秒。 我相信表变量的速度很慢,原因在此线程中列出: 表变量在 SQL Server 存储过程中插入时性能较差

临时表版本大约需要 1 秒,但由于 SQL Server 限制,我无法将其变成函数,并且我 将表返回给调用者。

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

预先非常感谢。

I have a relatively complex query, with several self joins, which works on a rather large table.
For that query to perform faster, I thus need to only work with a subset of the data.
Said subset of data can range between 12 000 and 120 000 rows depending on the parameters passed.

More details can be found here: SQL Server CTE referred in self joins slow

As you can see, I was using a CTE to return the data subset before, which caused some performance problems as SQL Server was re-running the Select statement in the CTE for every join instead of simply being run once and reusing its data set.

The alternative, using temporary tables worked much faster (while testing the query in a separate window outside the UDF body).
However, when I tried to implement this in a multi-statement UDF, I was harshly reminded by SQL Server that multi-statement UDFs do not support temporary tables for some reason...

UDFs do allow table variables however, so I tried that, but the performance is absolutely horrible as it takes 1m40 for my query to complete whereas the CTE version only took 40 seconds.
I believe the table variables is slow for reasons listed in this thread: Table variable poor performance on insert in SQL Server Stored Procedure

Temporary table version takes around 1 seconds, but I can't make it into a function due to the SQL Server restrictions, and I have to return a table back to the caller.

Considering that CTE and table variables are both too slow, and that temporary tables are rejected in UDFs, What are my options in order for my UDF to perform quickly?

Thanks a lot in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逆光飞翔i 2024-09-13 02:20:34

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

In many such cases all we need to do is to declare primary keys for those table variables, and it is fast again.

梦里南柯 2024-09-13 02:20:34

我使用的一种笨拙的解决方法涉及如下代码(伪代码如下):

CREATE TEMP TABLE #foo

EXECUTE MyStoredProcedure

SELECT *
 from #foo

GO

--  Stored procedure definition
CREATE PROCEDURE MyStoredProcedure
AS

INSERT #foo values (whatever)

RETURN
GO

简而言之,存储过程引用并使用由调用过程(或例程)创建的临时表。这会起作用,但如果您没有清楚地记录下来,其他人可能会感到困惑,无法了解正在发生的事情,并且您将得到重新编译、统计数据重新计算和其他奇怪的情况,可能消耗不需要的时钟周期。

One kludgey work-around I've used involves code like so (psuedo code follows):

CREATE TEMP TABLE #foo

EXECUTE MyStoredProcedure

SELECT *
 from #foo

GO

--  Stored procedure definition
CREATE PROCEDURE MyStoredProcedure
AS

INSERT #foo values (whatever)

RETURN
GO

In short, the stored procedure references and uses a temp table created by the calling procedure (or routine). This will work, but it can be confusing for others to follow what's going on if you don't document it clearly, and you will get recompiles, statistics recalcs, and other oddness that may consume unwanted clock cycles.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文