2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

如何缓存存储过程的结果

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

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

关注

评论

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

一个不用写代码的案例,来看看Flowable到底给我们提供了哪些功能?

江南一点雨

Java springboot flowable

Java基础知识(一些需要注意的点)

自然

9月日更 Java core 9月月更

leetcode 1110. Delete Nodes And Return Forest 删点成林(中等)

okokabcd

LeetCode 算法与数据结构

C++ 学习 ------cmath 头文件的源码学习 02

Java-fenn

Java

JavaScript 闭包难点剖析

Java-fenn

Java

不是吧,还有人不知道三目运算符的BUG

自然

Java core 9月月更

三个Spring的问题把我问懵逼了

知识浅谈

spring 9月月更

用typescript类型来实现快排

Java-fenn

Java

【1-2 Golang】Go语言快速入门—数组与切片

Java-fenn

Java

App Deploy as Code! SAE & Terraform 实现 IaC 式部署应用

Serverless Devs

2022年云堡垒机采购就选行云管家五大理由

行云管家

云计算 网络安全 数据安全 云堡垒机

CSS 有了:has伪类可以做些什么?

Java-fenn

Java

SQL 嵌套 N 层太长太难写怎么办?

陈橘又青

9月月更

利用AndroidNativeEmu完成多层jni调用的模拟

Java-fenn

Java

Java基础之Java枚举

自然

9月日更 Java core

前端食堂技术周刊第 52 期:Babel 7.19.0、Fresh 1.1、React Native 0.70、新的 Web 性能指标 INP

童欧巴

供应链金融能否成为汽车行业发展的驱动力?

旺链科技

区块链 产业区块链 汽车 供应链金融 企业号九月金秋榜

边缘计算和云计算之间的区别

Java-fenn

Java

中小企业如何有效应对计算资源的弹性变化需求?

Serverless Devs

敏捷发版:让灰度发布像commit一样简单

Speedoooo

小程序 灰度发布 小程序容器 A/B 测试

聊聊如何利用p6spy进行sql监控

Java-fenn

Java

性能之巅-优化你的程序

Java-fenn

Java

Java 流处理之收集器

Java-fenn

Java

如何设计一个面向未来的云原生数据库?

Zilliz

深度学习 数据库 云原生 信息检索 向量数据库

多云管理的挑战以及如何克服这些挑战

Java-fenn

Java

web技术分享| 虚拟列表实现

anyRTC开发者

Vue 前端 Web 音视频 虚拟列表

以软件定义物联网芯片,以技术融合推动LPWAN2.0泛在物联

ZETA开发者

芯片 物联网, LoRa LPWA DSP

TDengine 3.0 的 Update 有何区别?

TDengine

tdengine 时序数据库 企业号九月金秋榜

开源是什么意思?开源软件优缺点有哪些?

行云管家

开源 软件 开源软件 开源协议

MobPush开发过程常见问题

MobTech袤博科技

ios android 开发者

实战指南 | Serverless 架构下的应用开发

Serverless Devs

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