免费下载案例集|20+数字化领先企业人才培养实践经验 了解详情
写点什么

如何缓存存储过程的结果

  • 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:501658
用户头像

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

关注

评论

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

小红书基于 StarRocks 构建广告数据中心的实践

StarRocks

数据库 数据分析 StarRocks

Java泛型可行与不可行

编程江湖

DM 分库分表 DDL “乐观协调” 模式介绍丨TiDB 工具分享

PingCAP

react源码解析15.scheduler&Lane

buchila11

React

了解 Java 中的锁 Lock

Ayue、

ReentrantReadWriteLock ReentrantLock lock

给弟弟的信第22封|写技术博客有哪些益处?

大菠萝

28天写作

Linxu云计算这样学效率更快,Linux基础篇,expect-正则表达式-sed-cut的使用

学神来啦

Linux centos sed linux运维 expect

TCP 两次握手为什么无法阻止历史连接?

华为云开发者联盟

TCP 报文 握手 RST 报文 两次握手

react源码解析16.concurrent模式

buchila11

React

Gartner技术成熟曲线详解

Kafka中文社区

Azkaban工作流调度

恒生LIGHT云社区

工作流 工作流调度 任务调度 Azkaban

AI新手语音入门:认识词错率WER与字错率CER

华为云开发者联盟

语音识别 词错率 WER 字错率 CER

腾讯云商用密码合规解决方案,亮相2021商用密码应用创新高端研讨会

腾讯安全云鼎实验室

商用密码 云上安全 数字生态 安全服务

性能监控之 Golang 应用接入 Prometheus 监控

zuozewei

Prometheus 性能测试 性能监控 Go 语言 12月日更

PassJava 开源(五) :SpringCloud Alibaba 组件简介 #私藏项目实操分享#

悟空聊架构

SpringCloud 28天写作 passjava 悟空聊架构 12月日更

优秀程序员的30种思维--设计思考篇

hackstoic

程序员 架构思维

管理中的平衡

张老蔫

28天写作

如何有效使用预训练语言模型

云智慧AIOps社区

算法 智能运维 云智慧 语言模型 南加州大学

群聊泄密敲响警钟,WorkPlus织密信息安全“防护网”

WorkPlus

定了一份《人民日报》(23/28)

赵新龙

28天写作

使用 USE 方法分析系统性能瓶颈

耳东@Erdong

监控 28天写作 use 12月日更

服务器数量从21台降至3台,TDengine在跨越速运集团的落地实践

TDengine

数据库 tdengine 时序数据库

打造“智慧之眼”与“创新之轮”,华睿科技助推制造业智能升级

科技新消息

Log4j2 消停了,Logback 开始塌房了?

程序猿DD

Java 日志 漏洞

Java开发之线程、多线程,线程池面试题

@零度

多线程 线程池 JAVA开发

Flutter 完美的验证码输入框(2 种方法)【Flutter专题25】

坚果

flutter 28天写作 12月日更

如何用建木CI生成Allure报表

Jianmu

CI/CD Allure 国产开源

从科技出发,中科柏诚信云链为中小企业融资注入新动能

联营汇聚

“数”驰天下,华为云DRS 高效支撑T3出行平稳迁移

华为云开发者联盟

数据库 数据迁移 华为云DRS T3出行

Flutter开发:运行项目时提示Error parsing LocalFile:‘/Users/xxx/android/app/src/main/AndroidManifest.xml’…解决方法

三掌柜

28t 28天写作 12月日更

模块七 王者荣耀商城异地多活架构设计

小朱

架构实战营

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