避免多次调用 T-SQL 函数

Avoid calling T-SQL function multiple times

我有一个内联函数,在 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;

这是一个很长的脚本。我需要在不同的步骤中使用结果。我尝试创建一个临时文件 table,但过程太慢了。

上述查询有效,但我想让它更有效率。

一如既往,感谢您提出任何建议。

在 SQL 引擎中调用函数可能会非常慢。我建议创建一个视图,然后加入该视图——这样会快得多。如果我有时间我会给你一个例子

" 如果我​​使用一个视图,我可以多次使用视图结果还是每次使用视图结果 re-created?"

结果每次都是“re-created”,但是查询是经过编译的,这意味着您可以获得很多提高的性能。根据平台的不同,如果数据不脏,系统甚至可以缓存 re-use 查询数据。

另请注意,大多数系统都能够创建“物化视图”,然后将执行一次查询并将其存储为 table,直到您要求重新计算为止。这在 SQL Server、Oracle 和 DB2 上的工作方式不同,但您可以获得相同的功能。

对于某些系统来说,可以向视图添加参数(称为令人震惊的参数化视图),但我不推荐这样做——根据您的数据模型,可能有更好的方法来实现此功能(在您的情况下,我会例如,在视图中 select 之后进行分组。

还记得

  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