You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TSQL函数如何实现类似Python的memoization结果缓存功能?

TSQL 类 Python memoization 无侵入函数缓存实现方案

TSQL 无原生装饰器语法,无法完全实现 Python 那种无需修改任何代码即可为函数添加缓存的能力,但可通过以下两种简化路径实现需求,全程无需修改原函数的业务逻辑:

方案1:持久化缓存封装(最通用)

该方案适合跨会话、高频重复调用的场景,上层调用代码零修改:

  • 第一步:创建缓存存储表,结构和原函数的入参、返回值完全匹配,为入参字段加联合唯一索引加速查询。
    示例(原函数为dbo.HeavyCalc(@a int, @b varchar(50)) returns decimal(18,2)):
    CREATE TABLE dbo.FuncCache_HeavyCalc (
        a INT,
        b VARCHAR(50),
        Result DECIMAL(18,2),
        ExpireTime DATETIME DEFAULT DATEADD(DAY,7,GETDATE()), -- 可选,控制缓存过期
        CONSTRAINT PK_FuncCache_HeavyCalc PRIMARY KEY CLUSTERED (a, b)
    )
    
  • 第二步:重命名原函数,用原函数名创建封装函数,实现缓存命中判断逻辑:
    -- 重命名原函数
    EXEC sp_rename 'dbo.HeavyCalc', 'HeavyCalc_Original';
    GO
    -- 创建带缓存的封装函数,名称和原函数完全一致
    CREATE OR ALTER FUNCTION dbo.HeavyCalc(@a INT, @b VARCHAR(50))
    RETURNS DECIMAL(18,2)
    AS
    BEGIN
        DECLARE @Result DECIMAL(18,2)
        -- 优先查询未过期的缓存
        SELECT @Result = Result 
        FROM dbo.FuncCache_HeavyCalc 
        WHERE a = @a AND b = @b AND ExpireTime > GETDATE()
        IF @Result IS NOT NULL RETURN @Result
        -- 缓存未命中调用原函数计算
        SELECT @Result = dbo.HeavyCalc_Original(@a, @b)
        -- 结果写入缓存
        INSERT INTO dbo.FuncCache_HeavyCalc(a,b,Result)
        VALUES (@a, @b, @Result)
        RETURN @Result
    END
    GO
    
  • 注意:可搭配SQL Server代理作业定期清理过期缓存,避免表体积过大。

方案2:会话级临时缓存

该方案适合单会话内多次重复调用相同参数的场景,无需维护持久化存储,会话结束缓存自动清除:

EXEC sp_rename 'dbo.HeavyCalc', 'HeavyCalc_Original';
GO
CREATE OR ALTER FUNCTION dbo.HeavyCalc(@a INT, @b VARCHAR(50))
RETURNS DECIMAL(18,2)
AS
BEGIN
    DECLARE @Result DECIMAL(18,2)
    -- 会话缓存不存在则创建
    IF OBJECT_ID('tempdb..#FuncCache_HeavyCalc') IS NULL
    CREATE TABLE #FuncCache_HeavyCalc (
        a INT, b VARCHAR(50), Result DECIMAL(18,2),
        PRIMARY KEY CLUSTERED (a,b)
    )
    -- 查缓存
    SELECT @Result = Result FROM #FuncCache_HeavyCalc WHERE a = @a AND b = @b
    IF @Result IS NOT NULL RETURN @Result
    -- 计算并写入缓存
    SELECT @Result = dbo.HeavyCalc_Original(@a, @b)
    INSERT INTO #FuncCache_HeavyCalc(a,b,Result) VALUES (@a,@b,@Result)
    RETURN @Result
END
GO

以上两种方案均仅需要对原函数做重命名操作,无需修改任何业务代码,上层调用感知不到任何变化,是目前TSQL环境下最接近Python memoization能力的实现。

内容的提问来源于stack exchange,提问作者Krzysztof Krysztofczyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 22:15:07