SQL查询缓存

解析数据库领域 SQL 的查询缓存机制与优化 本文旨在全面解析SQL查询缓存的技术原理和优化方法,帮助数据库开发人员和管理员深入理解这一重要性能优化机制。讨论范围包括主流关系型数据库(MySQL、PostgreSQL、Oracle等)的查询缓存实现,但不涉及NoSQL数据库的特定缓存机制。文章首先介绍查询缓存的基本概念,然后深入其核心机制,接着探讨优化策略,最后通过实际案例展示应用方法。全文采用理论结合实践的方式,包含大量代码示例和性能分析。查询缓存(Query Cache):数据库系统用于存储查询结果的内存区域缓存命中(Cache Hit) 阅读详情
适合读者
本教程适合于那些对缓存SQL查询以减少数据库连接与执行的负载、提高脚本性能感兴趣的PHP程序员。
概述
许多站点使用数据库作为站点数据存储的容器。数据库包含了产器信息、目录结构、文章或者留言本,有些数据很可能是完全静态的,这些将会从一个缓存系统中得到的极大好处。
这样一个系统通过把SQL查询的结果缓存到系统的一个文件中存储,从而阻止连接数据库,构造查询与取得返回结果而提高了响应时间。
有些系统数据库并不是放在WEB服务器上的,这样需要一个远程连接(TCP或者其它类似的),或者从数据库中获取大量的数据,这样你得忍受更多时间,这决定于系统响应时间与资源利用。
前提
本教程使用MySQL作为数据库。你需要安装MySQL(www.mysql.com下载是有效的)和激活PHP MYSQL扩展(默认情况是激活的)。
由于要查询数据库,你需要知识一些SQL(结构化查询语言)的基本常识。
缓存SQL查询结果
为什么要缓存查询结果?
缓存查询结果能极大地改进脚本执行时间和资源需求。
缓存SQL查询结果也允许你通过后期处理数据。如果你用文件缓存去存储全部脚本的输出结果(HTML输出),这样可能是行不通的。
当你执行一个SQL查询时,点典的处理过程是:
<!--[if !supportLists]-->l        <!--[endif]-->连接数据库
<!--[if !supportLists]-->l        <!--[endif]-->准备SQL查询
<!--[if !supportLists]-->l        <!--[endif]-->发送查询到数据库
<!--[if !supportLists]-->l        <!--[endif]-->取得返回结果
<!--[if !supportLists]-->l        <!--[endif]-->关闭数据库连接
以上方法非常占用资源并且相反的影响了脚本的性能。只能通过取得的大量返回数据和数据库服务器的位置这二个要素来相互协调。尽管持续连接可以改进连接数据库时的负载,但非常耗费内存资源,如果获取的是大量的数据,那么存储的全部时间会非常短暂。
创建一条SQL查询:
SQL(结构化查询语言)查询被用作操作数据库及它内容的接口。SQL可用于定义和编辑表的结构,插入数据到表,更新或删除表中的信息。
SQL是用于与数据通讯的语言,在大多数PHP数据库扩展(MySQL,ODBC,Oracle等)通过传递SQL查询到数据库中来管理整个过程。
本教程中,仅仅用select语言来获取数据库中的数据。这些数据将被缓存,之后将用作数据源。
决定什么时候更新缓存:
根据程序的需要,缓存可以采取多种形式。最常见的3种方式是:
<!--[if !supportLists]-->l        <!--[endif]-->时间触发缓存(过期的时间戳)
<!--[if !supportLists]-->l        <!--[endif]-->内容改变触发缓存(发现数据改变后,相应地更新缓存)
<!--[if !supportLists]-->l        <!--[endif]-->人工触发缓存(人工的方式告知系统信息超期并且强制产生新的缓存)
你的缓存需求可能是以上原理的一个或多个的综合。本教程将讨论时间触发方式。然而,在一个全面的缓存机制中,3种方式的综合将被使用。
缓存结果:
基本的缓存是用PHP的两个函数serialize()和unserialize()(译注:这二个函数分别代表序列化与反序列化)。
函数serialize()用于存储PHP的值,它能保证不失去这些值的类型和结构。
事实上,PHP的session扩展是用序列化过的变量,把session变量($_SESSION)存储在系统的一个文件中。
函数unserialize()与以上操作相反并且使序列化过的字符串返回到它原来的结构和数据内容。
在本例中,以一个电子商务商店为例。商店有2个基本表,categories和products(此处为原始数据库表名).product表可能每天都在变化,categories仍然是不变静止的。
要显示产品,你可以用一个输出缓存脚本来存储输出的HTML结果到一个文件中。然而categories表可能需要后期处理。例如,所有的目录通过变量category_id(通过$_REQUEST['category_id']来取得)被显示,你可能希望高亮当前被选择的目录。
表categories结构
Field
Type 
Key
Extra
category_id
category_name
category_description
int(10) unsigned
varchar(255)
text
PRI
auto_incremen
 
 
在本例中,通过时间触发缓存技术被运用,设定一段时间后让其缓存SQL输出过期。在此特殊的例子中,定一段时间为24小时。
序列化例子:
<!--[if !supportLists]-->l        <!--[endif]-->连接数据库
<!--[if !supportLists]-->l        <!--[endif]-->执行查询
<!--[if !supportLists]-->l        <!--[endif]-->取得所有结果构成一个数组以便后面你可以访问
<!--[if !supportLists]-->l        <!--[endif]-->序列化数组
<!--[if !supportLists]-->l        <!--[endif]-->保存序列化过的数组到文件中
$file = 'sql_cache.txt'; 
$link = mysql_connect('localhost','username','password') 
    or 
die (mysql_error()); 
mysql_select_db('shop') 
    or 
die (mysql_error()); 
/* 构造SQL查询 */ 
$query = "SELECT * FROM categories"; 
$result = mysql_query($query) 
    or 
die (mysql_error()); 
while ($record = mysql_fetch_array($result) )
{ 
   
$records[] = $record; 
} 
$OUTPUT = serialize($records); 
$fp = fopen($file,"w"); // 以写权限的方式打开文件 
fputs($fp, $OUTPUT); 
fclose($fp); 
查看sql_cache.txt文件,里面的内容可能类似这样的:
a:1:{i:0;a:6:{i:0;s:1:"1";s:11:"category_id";s:1:"1";i:1;s:9:"Computers";s:13:"category_name";s:9:
"Computers" ;i:2;s:25:"Description for computers";s:20:"category_description"
;s:25:"Description for computers";}}
这个输出是它的变量和类型的内部表现形式。假若你用mysql_fetch_array()函数返回数字索引的数组和一个关联的数组(这就是为什么数据看起来像是发生了两次),一个是数字索引,另一个是字符串索引。
使用缓存:
要用缓存,你需要用函数unserialize()来使数据还原成原始格式与类型。
你可以用file_get_contents()这个函数来读取sql_cache.txt文件的内容,把它赋给一个变量。
请注意:这个函数在PHP4.3.0及以上版本有效。若你使用的是一个老版本的PHP,一个简单的方法是用file()函数(读整个文件到一个数组,每行变成一个数组)。implode()函数用于把数组的各元素连接成一个字符串然后使用unserialize()反序列化。
// file_get_contents() 适合于for PHP < 4.3.0
$file = 'sql_cache.txt';
$records = unserialize(implode('',file($file)));
现在你可以通过$records数组并且取得原始查询的数据:
foreach ($records as $id=>$row) {
    print $row['category_name']."<br>";
}
注意$records是数组(一个包含了查询结果的数字索引列——每行是一个数字和一个字符串...真是混乱)的一排。
把它们放在一块:
基于本例子中的时间来决定是否缓存。如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存。
<!--[if !supportLists]-->l        <!--[endif]-->检查文件是否存在并且时间戳小于设置的过期时间
<!--[if !supportLists]-->l        <!--[endif]-->获取存储在缓存文件中的记录或者更新缓存文件
<?php 
$file = 'sql_cache.txt'; 
$expire = 86400; // 24 小时 (单位:秒) 
if (file_exists($file) && 
filemtime($file) > (time() - $expire)) 
{ 
    
// 取得缓存中的记录
    $records = unserialize(file_get_contents($file)); 
} 
else { 
    
// 通过 serialize() 函数创建缓存 
} 


?>
附加其它可能的:
<!--[if !supportLists]-->l        <!--[endif]-->把缓存结果存储在共享内存中以获取更快的速度
<!--[if !supportLists]-->l        <!--[endif]-->增加一个功能随机地运行SQL查询并且检查是否输出与缓存输出一致。如果不一致,则更新缓存(本函数运行次数的概率可以定为1/100)。通过哈希算法(如MD5())可以协助判断字符串或者文件是否改变。
<!--[if !supportLists]-->l        <!--[endif]-->增加一个管理员的功能,人工的删除这个缓存文件,以强制更新缓存(如file_exists()函数返回false时)。你可以用函数unlink()删除文件。
脚本:
<?php
$file = 'sql_cache.txt'; 
$expire = 86400; // 24 小时 
if (file_exists($file) && 
    
filemtime($file) > (time() - $expire)) { 
    
$records = unserialize(file_get_contents($file)); 
} 
else { 
    
$link = mysql_connect('localhost','username','password') 
        or 
die (mysql_error()); 
    
mysql_select_db('shop') 
        or 
die (mysql_error()); 
    
/* 构造SQL查询 */ 
    
$query = "SELECT * FROM categories"; 
    
$result = mysql_query($query) 
        or 
die (mysql_error()); 
    
while ($record = mysql_fetch_array($result) ) { 
        
$records[] = $record; 
    } 
    
$OUTPUT = serialize($records); 
    
$fp = fopen($file,"w"); 
    
fputs($fp, $OUTPUT); 
    
fclose($fp); 
} 
// end else 
 
// 查询结果在数组 $records 中 

foreach ($records as $id=>$row) { 
    
if ($row['category_id'] == $_REQUEST['category_id']) { 
        
// 被选择的目录显示粗体字 
        print '<B>'.$row['category_name'].'</B><BR>'; 
    } 
else { 
        
// 其它目录显示用常规字体 
        print $row['category_name'].'<br>'; 
    } 
} 
// end foreach 


?>
关于作者
Ori Staub是专注于研究基于WEB解决方案的中级系统分析员,开发者和顾问。可以通过电子邮件os@zucker-staub.com联系他。
原文地址:http://www.zend.com/zend/tut/tutorial-staub2.php
 
mysql缓存设置(查询缓存) 一、概念 1、从 MySQL4开始,出现了QueryCache查询缓存,如果使用了QueryCache,当查询接收到一个和之前同样的查询,服务器将会从查询缓存中检索结果,而不是再次分析和执行上次的查询。这样就大大提高了性能,节省时间,非常有用。 2、缓存存在一个hash表中,通过查询SQL,查询数据库,客户端协议等作为key.在判断是否命中前,MySQL不会解析SQL,而是直接使用SQL去查询缓存,SQL任何字符上的不同,如空格,注释,都会导致缓存不命中。如果查询中有不确定数据,例如CURRENT_DATE 阅读详情

相关推荐

SQL 在数据库领域的查询缓存优化策略

在数据库系统中,查询操作是非常频繁的。每次执行相同的 SQL 查询时,如果都要重新进行数据检索、计算和处理,会消耗大量的系统资源和时间,导致数据库性能下降。查询缓存的目的就是为了避免重复执行相同的查询,提高数据库的查询性能。本文的范围涵盖了各种常见数据库(如 MySQL、Oracle、SQL Server 等)的查询缓存机制,探讨如何通过有效的优化策略来提升查询缓存的使用效率。本文将按照以下结构展开:首先介绍查询缓存的核心概念与联系,让读者对查询缓存有一个清晰的认识;

2502_91592937的博客 1047

C# SqlSugar框架的学习使用(七)-- 二级缓存的使用

前言上一篇《C# SqlSugar框架的学习使用(六)-- 扩展用法》把一些常用的扩展用法已经做了出来,本篇就来讲一下SqlSugar高级用法中的二级缓存功能。二级缓存功能介绍及使用方法...

Vaccae的博客 4013

SqlSugar框架的学习使用

SqlSugar 是一款简单易用的开源 ORM 框架,支持.NET CORE 和 MySql、SqlServer、Sqlite、Oracle 、 postgresql 、达梦、人大金仓 数据库,具有 EF NH 的功能,比 EF 更人性化的语法,支持真实的批量操作,另外还有媲美 DAPPER 的性能。 优点: 1、优越的性能,查询使用 reflection.emit 创建IL语言+委托绑定 然后对该对象进行 cache ,datareader直接赋值给cache对象,高性能拉姆达解析,总体性能媲美 http://ADO.NET ,查询速度稍慢于datareader但稍快于datatable 2、大量语法糖,拉姆达表达示筛选,新颖的多表查询 ,方便的分页等 3、支持NOLOCK查询,提高性能 4、支持事务 5、内置实体类生成函数,无需使用第三方代码生成器 6、简单好用、例子齐全有问必答。 7、支持.NET CORE 和 MySql、SqlServer、Sqlite、Oracle 、 postgresql 、达梦、人大金仓 数据库,具有EF NH的功能,比EF更人性化的语法,支

使用SqlSugar封装的数据层基类

首先简单封装了个DbContext 1 public class DbContext 2 { 3 #region 属性字段 4 private static string _connectionString; 5 6 /// <summary> 7 /...

dengxuanxian9113的博客 3910

阿里云百炼平台创建智能体-上传文档

阿里云百炼智能体-上传文档文件

weixin_43930851的博客 1356

告别TI官网迷路!手把手教你用C2000Ware为TMS320F28027搭建Proteus仿真工程模板

本文详细指导如何使用C2000Ware为TMS320F28027搭建Proteus仿真工程模板,帮助DSP开发者快速上手。从资源获取、工程目录设计到关键文件配置,再到CCS与Proteus的联调技巧,全面解析仿真工程搭建的每个步骤,特别适合初学者和工程师参考。

weixin_42715608的博客 472

SQLSugar进阶使用:高级查询与性能优化

SqlSugar作为一款专为.NET平台设计的轻量级ORM(对象关系映射)框架,其进阶使用中的高级查询与性能优化涵盖了多个方面的内容。综上所述,SqlSugar的高级查询功能提供了强大的数据筛选、排序和连表查询能力,而性能优化则通过缓存、SQL优化、批量操作等多种手段来提高数据库操作的效率。这些特性使得SqlSugar在.NET开发领域具有广泛的应用前景。“笑对人生,智慧同行!博客新文出炉,微信订阅号更新更实时,等你笑纳~”

m0_74823611的博客 5519

基于MATLAB/Simulink的四旋翼无人机PID控制与仿真(3)

《基于MATLAB/Simulink的四旋翼无人机PID控制与仿真》的第三篇,将为大家继续展示并完善控制与仿真模型。本文将在前文的基础上,完成控制环节增补、参数设置、测试等工作,在不考虑性能(低超调、快、准等)的前提下,保证系统对于一般输入(阶跃、斜坡)的响应稳定性。

jlx142857的博客 9321

sql server 缓存_搜索SQL Server查询计划缓存

sql server 缓存 Whenever a query is executed in SQL Server, its execution plan, as well as some useful execution data are placed into the plan cache for future use. This information is a treasure tr...

culuo4781的博客 1099

在中国大陆使用 LiveKit 集成阿里云语音交互服务

通过集成阿里云的语音和模型服务,我们可以快速构建出适合中国用户的 LiveKit 智能语音应用。LiveKit Agents 框架的模块化设计使得替换底层服务变得异常简单,只需要更换相应的插件实例即可。使用 WebSocket 版本的阿里云 ASR 接口以获得更低的延迟。利用通义千问的 Function Calling 能力对接智能家居或企业内部 API。结合 LiveKit 的视频处理能力,打造具备视觉交互的数字人。希望这篇博客能为你在实时音视频与 AI 结合的探索之路上提供帮助!

星空漫野 1236

【Claude Code】Extra inputs are not permitted 报错:代理网关剥离 Beta 标头的修复

通过代理或 LLM 网关连接 Anthropic API 时,Claude Code 报 "Extra inputs are not permitted"?根因是中间件删除了 anthropic-beta 请求标头,导致 Beta 字段被 API 拒绝。本文详解标头转发配置和 CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS 回退方案。

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 125

hibernate 查询缓存,以及在关联表查询缓存下使用HQL,而不是sql去查询

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33845477的博客 172

具身智能(26):RDK S100的LeRobot或Agile X piper机械臂控制模型

本文档详细介绍了基于ROS2的机器人控制模型架构与标定数据联动机制。核心采用"感知-规划-控制"闭环流程,通过激光雷达、相机和IMU的融合数据实现厘米级定位(≤1cm)。文档包含两大控制模型配置:1)RDKLeRobot模型,重点说明PID参数调节和标定文件路径设置;2)AgileXPiper模型,强调驱动安装与外部标定文件集成。针对常见问题提供解决方案,如控制指令无响应需验证标定路径,运动偏差过大需重新标定等。最后给出批量部署方案,通过复制基准配置文件实现多机器人快速配置,要求定位偏差

码农17年的博客 179

对mysql查询缓存及sql_mysql – SQL查询缓存

两个澄清开头:> MySQL查询缓存是服务器端功能,没有“本地缓存”这样的东西.你可能会对FLUSH命令中的LOCAL关键字感到困惑.正如docs解释的那样,它只是NO_WRITE_TO_BINLOG的别名(因此它与复制有关,“本地”意味着“此服务器”).>如果您启用了该功能,MySQL将仅返回缓存数据,并将其设置为默认值或选择使用SQL_CACHE提示.根据我的经验,大多数服务器默认...

weixin_39528467的博客 310

【思考模型框架】前景理论(Prospect Theory),认为人们并不是完全理性的决策者,而是根据一些心理上的偏差来评估选项的价值

前景理论,是一种行为经济学理论。前景理论,描述了人们在不确定条件下如何作出决策。前景理论,认为人们并不是完全理性的决策者,而是根据一些心理上的偏差来评估选项的价值。

奶爸的编程之路,也就一周冷个三天 1642

全网最全RT-DETR涨点改进,基于官方源码1:1还原,在Ultralytics项目中配置rtdetr-r18、rtdetr-r34、rtdetr-r50、rtdetr-r101版本~小论文大论文必备

本文详细介绍了如何将RT-DETR的ResNet18/34/50/101/154版本移植到ultralytics项目中。主要内容包括:1) RT-DETR核心特点,如高效混合编码器、IoU感知查询选择等;2) 提供完整ResNet核心代码;3) 分步配置指南,包括创建模块文件和修改tasks.py;4) 各版本yaml配置文件的创建方法。该方案可帮助研究者快速实现RT-DETR改进,适用于目标检测相关论文研究。所有配置文件均可正常运行,为实验部署提供了便利。

Ai缝合怪、助力小伙伴高效发论文 3925

PHP缓存的实现之SQL查询缓存

适合读者 本教程适合于那些对缓存SQL查询以减少数据库连接与执行的负载、提高脚本性能感兴趣的PHP程序员。 概述 许多站点使用数据库作为站点数据存储的容器。数据库包含了产器信息、目录结构、文章或者留言本,有些数据很可能是完全静态的,这些将会从一个缓存系统中得到的极大好处。

shao.bing的专栏 943

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

对mysql查询缓存及sql_mysql – SQL查询缓存

两个澄清开头:> MySQL查询缓存是服务器端功能,没有“本地缓存”这样的东西.你可能会对FLUSH命令中的LOCAL关键字感到困惑.正如docs解释的那样,它只是NO_WRITE_TO_BINLOG的别名(因此它与复制有关,“本地”意味着“此服务器”).>如果您启用了该功能,MySQL将仅返回缓存数据,并将其设置为默认值或选择使用SQL_CACHE提示.根据我的经验,大多数服务器默认...

weixin_35242442的博客 154

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

SQL查询缓存[转载]

概述 许多站点使用数据库作为站点数据存储的容器。数据库包含了产器信息、目录结构、文章或者留言本,有些数据很可能是完全静态的,这些将会从一个缓存系统中得到的极大好处。 这样一个系统通过把SQL查询的结果缓存到系统的一个文件中存储,从而阻止连接数据库,构造查询与取得返回结果而提高了响应时间。 有些系统数据库并不是放在WEB服务器上的,这样需要一个远程连接(TCP或者其它类似的),或者...

处事如水 187

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

MyBatis 从入门到精通(第三篇)—— 动态 SQL、关联查询与查询缓存

本文深入探讨MyBatis三大高级特性:动态SQL、关联查询和查询缓存。动态SQL通过if、where、foreach等标签实现灵活SQL拼接;关联查询利用association和collection处理一对一、一对多关系;查询缓存包括一级和二级缓存,并介绍与Ehcache的集成方法。文章还提供实体类定义、Mapper配置和测试代码示例,帮助开发者掌握复杂业务场景下的数据持久化解决方案。建议合理使用这些特性,如动态SQL简化条件拼接,关联查询处理多表关系,高频查询场景启用二级缓存,以提升系统性能和开发效率。

a15585391608的博客 1231
上一篇: PHP缓存技术
下一篇: PHP内容缓存输出 PEAR cache
cqinter
博客等级 码龄21年 14粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值