2017-01-09 101 views
1

我有一个具有计算价格,折扣,配额,地点,日期,房间等的可用性复杂的SQL查询在SQL Server缓存查询结果Asyncronuosly

当访问者搜索房间,按日期,人物,第一次放置等, 我试过尽快返回第一页结果。

在第一页我只是分析前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与prameters和防止多个呼叫我将不胜感激工作的例子。

谢谢。

+0

为什么你认为你需要这些? SQL Server已经为你自己做了大量的缓存。 – RBarryYoung

+0

因为我想尽快返回第一页。如果我计算第一页请求的所有结果。这将需要很长时间。在第一页之后,客户端可以选择价格顺序,或者按照某些类别,便利设施等进行过滤。另外,我测试过,缓存在表上的缓存从SQL自己的缓存中返回5倍。因为有很多逻辑计算。 –

回答

0

没有阅读所有细节,我只解决这部分:

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)。