【问题标题】:Caching Query Results in SQL Server Asyncronuosly在 SQL Server 中异步缓存查询结果
【发布时间】:2017-01-09 22:40:26
【问题描述】:

我有一个复杂的 SQL 查询,它计算价格、折扣、配额、地点、日期、房间可用性等。

当访客第一次按日期、人员、地点等搜索房间时, 我尝试尽快返回首页结果。

在第一页我只分析前 20 名设施价格、配额、折扣等。

现在我想在准备好第一页时将所有列表缓存在缓存表中以进行分页和过滤。

我的 SP 是;

GetResultsPage:

如果有缓存,则该SP从缓存表中返回页面结果,如果没有缓存,则返回第一页。

CreateCache

这个 SP 计算并插入一个完整的结果列表到缓存表中,CacheId

目前我在返回第一页结果后从客户端服务调用CreateCache

我知道,我可以从 C# 创建一个后台作业,或者在第一次请求时从客户端发送并行请求。但是如果有 2 或 3 个访问者同时使用相同的参数搜索,就会出现相同的冲突。因为缓存列表基于搜索参数。这不是个人的。

我正在考虑创建一个可以管理缓存列表的 SQL 代理作业。流程如下。

1- 请求来到“GetResultsPage”

2-如果有缓存且缓存时间不超过30分钟,则从缓存表返回结果

3-如果有缓存且缓存时间超过30分钟,结果返回第一页

4- 如果不需要缓存或重新创建缓存,我应该使用参数异步调用CreateCache

5- 当CreateCache 运行时,另一个CreateCache 不应使用相同的参数运行。

我需要一些关于我的策略的建议,并听取一些关于 SQL 代理工作的经验是否对性能有任何负面影响。

另外,如果有一个工作示例可以运行带有参数的CreateCache SP 并防止多次调用,我将不胜感激。

谢谢。

【问题讨论】:

  • 你为什么认为你需要这些? SQL Server 已经自行为您完成了大量缓存。
  • 因为我想尽快返回首页。如果我计算第一页请求的所有结果。这将需要很长时间。在第一页之后,客户可以选择价格顺序,或按某些类别、设施等进行过滤。我还测试过,在表上缓存从 SQL 自己的缓存中返回快 5 倍。因为有很多逻辑计算。

标签: sql sql-server sql-server-2014


【解决方案1】:

在不阅读所有细节的情况下,我将只讨论这部分:

5- 当CreateCache 运行时,不应运行另一个CreateCache 具有相同的参数。

这很容易通过sp_getapplock 实现。

CREATE PROCEDURE [dbo].[CreateCache]
    -- Add the parameters for the stored procedure here
    @Param1 int
    ,@Param2 int
AS
BEGIN
    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    BEGIN TRANSACTION;
    BEGIN TRY
        DECLARE @VarResource nvarchar(255) = 'CreateCache';
        SET @VarResource = @VarResource + '_' + CAST(@Param1 AS nvarchar(255));
        SET @VarResource = @VarResource + '_' + CAST(@Param2 AS nvarchar(255));

        DECLARE @VarLockResult int;
        EXEC @VarLockResult = sp_getapplock
            @Resource = @VarResource,
            @LockMode = 'Exclusive',
            @LockOwner = 'Transaction',
            @LockTimeout = 1, -- play with timeout
            @DbPrincipal = 'public';

        IF @VarLockResult >= 0
        BEGIN
            -- Acquired the lock
            -- Populate the cache

        END ELSE BEGIN
            -- do nothing, because there is another instance running already
        END;

        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
    END CATCH;
END

@Resource 名称由参数值组成,因此第二次尝试使用相同的参数集调用此过程将不会获得锁。 如果你有很多参数,不适合 255 个字符,你可以计算一个哈希值(参见HASHBYTES)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多