避免多次调用T-SQL函数

时间:2020-10-08 16:39:25

标签: sql sql-server tsql inline-functions

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

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

上面的查询有效,但我想使其更有效。

一如既往,谢谢您的任何建议。

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