我有一个内联函数,导致在执行T-SQL脚本期间需要多次。该函数的结果很大。我试图弄清楚如何只调用一次函数。
这是我的功能:
CREATE OR ALTER FUNCTION getRecords (@earliestDate Datetime, @token1 varchar(64), @token2 varchar(64))
RETURNS TABLE
AS
RETURN
(
SELECT CONVERT(DATE, LogDate) AS LogDate, UserType, UserStatus
FROM LogTable WITH (NOLOCK)
WHERE UserStatus = 'Active'
AND LogDate >= @earliestDate
AND (token = @token1 OR token = @token2)
GROUP BY LogDate, UserType, UserStatus
);
GO
我稍后需要在脚本的不同位置使用结果。例如:
DECLARE @token1 varchar(64) = '1111'
DECLARE @token2 varchar(64) = '9999'
DECLARE @earliestDate Datetime='2020-09-01';
SELECT Product, UserType,
(SELECT COUNT(DISTINCT UserStatus)
FROM getRecords (@earliestDate, @token1, @token2) AS GR
INNER JOIN mySecondTable AS ST
ON GR.UserType = ST.UserType
) AS MyCount
FROM ProductTypes INNER JOIN getRecords (@earliestDate, @token1, @token2) AS GR2
ON ProductTypes.UserType = GR2.UserType;
WHERE ProductTypes.avail = 1;
这是一个很长的脚本。我需要在不同步骤中使用结果。我尝试创建一个临时表,但是过程太慢了。
上面的查询有效,但我想使其更有效。
一如既往,谢谢您的任何建议。
答案 0 :(得分:1)
在SQL引擎中,调用函数可能非常慢。我建议创建一个视图,然后再加入该视图-这应该更快。如果有时间,我会给你写个例子
“如果使用视图,是否可以多次使用视图结果,还是每次使用时都会重新创建视图结果?”
每次都会“重新创建”结果,但是会编译查询,这意味着您可以获得很多提高的性能。如果平台不脏,系统甚至可能会根据数据平台对数据进行重用查询的缓存。
还请注意,大多数系统都具有创建“物化视图”的能力,然后该视图将执行一次查询并将其存储为表格,直到您要求重新计算它为止。这在SQL Server,Oracle和DB2上的工作方式不同,但是您可以获得相同的功能。
对于某些系统可以添加参数进行查看(称为令人震惊的参数化视图),但我不建议这样做-根据您的数据模型,可能有更好的方法来实现此功能(在您的情况下,我可以例如,在我从视图中选择后进行分组。
还记得
AND (token = @token1 OR token = @token2)
与
相同 AND token IN (@token1, @token2)
但是某些平台可能不支持以这种方式使用参数。在这种情况下,您可能可以使用这样的联接
WITH filter(t) AS
(
VALUES (@token1),
(@token2)
)
SELECT x
FROM y
JOIN filter ON filter.t = y.token