BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

如何缓存存储过程的结果

| 作者 马德奎 关注 0 他的粉丝 发布于 2014年4月1日. 估计阅读时间: 6 分钟 | 如何结合区块链技术,帮助企业降本增效?让我们深度了解几个成功的案例。

Brent Ozar是咨询公司Brent Ozar Unlimited的创始人和负责人,同时也是一名微软最有价值专家和SQL Server DBA。他发表了一篇博文,介绍一种缓存存储过程结果的方案及应用场景。

在文章开头,他给出了这样一个场景:一家在线商店需要在每个物品的页面上显示用户买过的相关产品。他认为,在完美的世界中,这些数据应该在Web/应用层缓存。但是,有时候,开发人员会构建存储过程来获取这类数据,而最终存储过程的调用过于频繁。

Brent指出,对于这种已经使用了存储过程的情况,可以构建一个缓存供存储过程使用。

假如加入缓存层之前的代码如下:

CREATE PROCEDURE dbo.usp_GetRelatedItems
@ItemID INT AS
BEGIN
SELECT RelatedItemID,RelatedItemName
FROM dbo.BigComplicatedView
WHERE SoldItemID=@ItemID;
END
GO

代码一:原来的存储过程

则加入缓存层之后的代码如下:

CREATE PROCEDURE dbo.usp_GetRelatedItems
    @ItemID INT AS
BEGIN
  IF EXISTS(SELECT * FROM Cache.dbo.GetRelatedItems
            WHERE ItemID=@ItemID)
      SELECT * 
      FROM Cache.dbo.GetRelatedItems
      WHERE ItemID=@ItemID
  ELSE
      SELECT RelatedItemID,RelatedItemName
      FROM dbo.BigComplicatedView
      WHERE SoldItemID=@ItemID;
END
GO

代码二:实现缓存(一)

代码二引入了一个新表Cache.dbo.GetRelatedItems,其中Cache是新建的数据库。该表中的列比usp_GetRelatedItems的返回结果多了一个输入字段和一个ID,其格式如下:

该表中的数据可以根据需要每天晚上或者每周进行一次truncate。另外,在实际工作中实现这样一个方案时,他还会根据大量A/B性能测试的结果创建恰当的聚簇索引。

代码二并未对缓存表进行操作。如果数据没有缓存,其实需要将其插入缓存表,代码如下:

CREATE PROCEDURE dbo.usp_GetRelatedItems
    @ItemID INT AS
BEGIN
  /*查看待查找的记录是否已经缓存*/
  IF NOT EXISTS(SELECT * FROM Cache.dbo.GetRelatedItems
            WHERE ItemID=@ItemID)
      BEGIN 
        /*缓存中没有记录,因此插入缓存*/
        INSERT INTO Cache.dbo.GetRelatedItems
          (ItemID,RelatedItemID,RelatedItemName)   
        SELECT RelatedItemID,RelatedItemName
        FROM dbo.BigComplicatedView
        WHERE SoldItemID=@ItemID;
      END
  /*从缓存中获取记录*/    
  SELECT * 
  FROM Cache.dbo.GetRelatedItems
  WHERE ItemID=@ItemID      
END
GO

代码三:实现缓存(二)

他承认,这种做法会增加SQL Server的写负载,但他只有在面临下面这些情况时才使用这种方案:

  • 操作极为密集但只读的存储过程
  • 调用非常频繁(每分钟几百或几千次)
  • 其结果变化频率少于每天一次(或者不关心实时精度)
  • 业务需要非常快的系统改进速度,没有时间等着开发人员实现一个缓存层

最后,他指出,这只是紧急情况下让业务恢复运行的一种创可贴式方案。另外,他还推荐了一些与缓存相关的资源,包括最快的查询是不用执行的那个选择缓存方式通过缓存让系统更好地运行。有兴趣的读者可以进一步阅读。


感谢包研对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

就一句话评价:请做正确的事情! by shi leo

请问作者是否考虑过单元测试和maintain的问题? 请问这种方式难道真的比正确在web上实现一层cache要容易吗?

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT