写点什么

如何缓存存储过程的结果

  • 2014-03-31
  • 本文字数:1332 字

    阅读完需:约 4 分钟

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 )关注我们,并与我们的编辑和其他读者朋友交流。

2014-03-31 07:501849
用户头像

发布了 256 篇内容, 共 90.9 次阅读, 收获喜欢 12 次。

关注

评论

发布
暂无评论
发现更多内容

C++ 数学函数、头文件及布尔类型详解

小万哥

程序人生 编程语言 软件工程 C/C++ 后端开发

产品经理能力模型

执于业务

详解数仓对象设计中序列SEQUENCE原理与应用

华为云开发者联盟

数据库 华为云 华为云开发者联盟 华为云GaussDB(DWS) 企业号2024年4月PK榜

ZKFair 步入Dargon Slayer 新阶段,未来还有哪些财富效应?

鳄鱼视界

BSN-DID研究--主题一:DID API

BSN研习社

区块链 did

浅谈JVM整体架构与调优参数

华为云开发者联盟

JVM 华为云 Java虚拟机 华为云开发者联盟 企业号2024年4月PK榜

ZKFair 创新之旅,新阶段如何塑造财富前景

加密眼界

ZKFair 创新之旅,新阶段如何塑造财富前景

股市老人

ZKFair 步入Dargon Slayer 新阶段,未来还有哪些财富效应?

股市老人

假如AI圈有世纪大和解

脑极体

AI

关于 ASP.NET Core 中的静态文件

雄鹿 @

ASP.NET Core

你们单测覆盖率是如何统计的?原理是什么?

派大星

测试 单元测试 Java 面试题 互联网大厂面试 单测覆盖率

Databend 开源周报第 138 期

Databend

新质生产力崛起,运营商前端运营如何跃升

鲸品堂

前端 运营 运营商

Druid MySQL连接池本地实践

FunTester

ZKFair 步入Dargon Slayer 新阶段,未来还有哪些财富效应?

石头财经

ZKFair 创新之旅,新阶段如何塑造财富前景

BlockChain先知

仿真黑科技EasyGo DeskSim 2022

芯动大师

Kyligence 正式加入华为“同舟共济”行动计划,成为行业数智化“联盟级伙伴”

Kyligence

SQLynx发布3.0.0版本:带来更流畅便捷的SQL开发体验

先锋IT

cad 2024 mac下载 cad设计绘图软件,AutoCAD 2024破解版安装教程

Rose

System.gc 之后到底发生了什么 ?

bin的技术小屋

GC Java】 JVm虚拟机 #JVM

containerd配置HTTP私仓

GousterCloud

私有仓库 Containerd

百度“超模”、三大开发神器组团出道?李彦宏2024年度演讲提前剧透!

三掌柜

原型图设计思路总结

执于业务

如何缓存存储过程的结果_语言 & 开发_马德奎_InfoQ精选文章