MySQL的Query Cache和PostgreSQL的pg_prewarm详解

 更新时间:2025年07月24日 09:42:13   作者:喝醉酒的小白  
MySQL QueryCache(已废弃)缓存SQL结果,依赖全匹配且数据不变,高并发写时性能差;PostgreSQL pg_prewarm预加载数据页至共享缓冲区,提升冷启动效率,需手动维护,建议用应用层缓存或InnoDB BufferPool替代

MySQL 的 Query CachePostgreSQL 的 pg_prewarm核心功能、原理机制、使用建议、适用场景、对比分析

一、MySQL 的 Query Cache(查询缓存)【已废弃】

功能概述

MySQL 的 Query Cache 是一个用于缓存 SQL 查询结果的全局缓存,当完全相同的 SQL 被再次执行时,可以直接返回缓存结果,跳过解析、优化、执行流程。

原理机制

  • 查询缓存的是 结果集(Result Set),不是执行计划。
  • 只有完全相同的 SQL 字符串(包括空格、大小写)才能命中缓存。
  • 当表中的数据发生变化(如 INSERT/UPDATE/DELETE),该表相关的缓存会全部失效。
  • Query Cache 是全局唯一的,不分库表、用户,也不是线程局部缓存。

主要参数:

query_cache_type = 1           # 0=off, 1=on, 2=DEMAND
query_cache_size = 64M         # 缓存总大小
query_cache_limit = 1M         # 单条查询最大缓存

优缺点:

优点缺点
小型、读多写少场景命中率高,减少 CPU 和磁盘压力易导致全局锁争用,数据一变即清空相关缓存,命中率低
查询速度可极大提升(只要 SQL 和表数据都未变化)高并发写时性能下降严重,适得其反;多核扩展性差

注意事项:

  • MySQL 5.7 开始默认关闭,8.0 已完全移除(废弃)。
  • 在现代系统中,推荐使用应用层缓存(如 Redis)、Proxy 层缓存或使用 InnoDB Buffer Pool(页缓存)而非 Query Cache。

二、PostgreSQL 的 pg_prewarm(页级预热)

功能概述

PostgreSQL 的 pg_prewarm 是一个 将表或索引数据加载进共享缓冲区(shared_buffers) 的扩展模块,常用于数据库重启后的 热数据预加载(预热),加快数据库“恢复访问性能”。

原理机制

  • PostgreSQL 使用 Buffer Pool(共享缓冲区) 管理数据页,冷启动时缓存为空。
  • pg_prewarm 可以将指定的表、索引页主动读取进缓存,避免冷启动时慢查询。
  • 可以搭配 auto_preload_libraries 自动在启动时加载,也可以定期 dump 热页信息并在启动恢复。

使用方式

-- 加载扩展
CREATE EXTENSION IF NOT EXISTS pg_prewarm;

-- 手动预热某表
SELECT pg_prewarm('mytable');

-- 指定预热方式(可选:prefetch, read, buffer, read_async)
SELECT pg_prewarm('mytable', 'prefetch');

配合自动预热使用

  1. 开启插件:
shared_preload_libraries = 'pg_prewarm'
  1. 使用 pg_buffercache + pg_prewarm 定期导出热数据页,在重启后恢复:
SELECT * FROM pg_buffercache LIMIT 10;
-- 使用 extension 来结合自动恢复机制

优缺点:

优点缺点
明确、主动地提升关键数据表冷启动性能非自动缓存,需额外维护策略与脚本
适合大表/索引重启预热,提升系统恢复性能如果 shared_buffers 太小,效果有限

三、对比总结

特性 / 系统MySQL Query CachePostgreSQL pg_prewarm
缓存内容SQL 查询结果数据页(blocks)
缓存粒度SQL 层存储层(页级别)
命中条件SQL 完全相同且数据未改动无需精确 SQL,可按表预热
一致性影响高(数据更新后清除缓存)无影响(数据页始终一致)
是否自动可自动缓存需手动或脚本维护
现代支持情况MySQL 8.0 移除PostgreSQL 官方推荐扩展
推荐替代方案Redis 缓存 + InnoDB Buffer Pool使用 shared_buffers + pg_prewarm

实战建议

若你是运维/PostgreSQL DBA

建议使用 pg_prewarm 结合 pg_buffercache、监控热页访问模式,定期导出热数据页信息,并写入 cron 脚本,在系统重启后调用预热脚本提升性能。

若你还在使用老版本 MySQL(5.6/5.7)

避免启用 Query Cache(除非是非常小的读密集型场景),建议通过应用层缓存 + InnoDB 参数优化提升查询效率。

  • 使用 InnoDB 缓冲池预热
innodb_buffer_pool_dump_at_shutdown = 1
innodb_buffer_pool_load_at_startup = 1

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Mysql 日期时间 DATE_FORMAT(date,format)

    Mysql 日期时间 DATE_FORMAT(date,format)

    Mysql 日期时间 DATE_FORMAT(date,format) ,需要的朋友可以参考下。
    2010-12-12
  • MySQL事务与隔离级别的使用基础理论

    MySQL事务与隔离级别的使用基础理论

    这篇文章主要介绍了MySQL事务的隔离级别详情,事务隔离级别越高,为避免冲突所花费的性能也就越多,即效率低。在“可重复读”级别,实际上可以解决部分的虚读问题,但是不能防止update更新产生的虚读问题,要禁止虚读产生,还是需要设置串行化隔离级别
    2023-02-02
  • MySQL插入数据与查询数据

    MySQL插入数据与查询数据

    这篇文章主要介绍了 MySQL插入数据与查询数据,缺省插入、缺省插入、缺省插入等各种数据插入分享,需要的小伙伴可以参考一下,希望对你有所帮助
    2022-03-03
  • linux下mysql开启远程访问权限 防火墙开放3306端口

    linux下mysql开启远程访问权限 防火墙开放3306端口

    这篇文章主要为大家详细介绍了linux下mysql开启远程访问权限,防火墙开放3306端口,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • MySQL存储数据乱码的问题解析

    MySQL存储数据乱码的问题解析

    这篇文章主要介绍了MySQL存储数据乱码的问题解析,作者从实际使用中的多个方面定位其原因然后解决,需要的朋友可以参考下
    2015-05-05
  • mysql数据库重命名语句分享

    mysql数据库重命名语句分享

    这篇文章主要介绍了mysql数据库重命名语句救命示例,语句中的数据库表前缀换成自己的就可以了,大家参考使用吧
    2014-01-01
  • 深入理解Mysql的四种隔离级别

    深入理解Mysql的四种隔离级别

    开发工作中我们会使用到事务,那你们知道事务又分哪几种吗?MYSQL标准定义了4类隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低的隔离级一般支持更高的并发处理,并拥有更低的系统开销。下面通过这篇文章我们来一起深入理解Mysql中的四种隔离级别。
    2016-11-11
  • Mysql迁移到TiDB双写数据库兜底方案详解

    Mysql迁移到TiDB双写数据库兜底方案详解

    这篇文章主要为大家介绍了Mysql迁移到TiDB双写数据库兜底方案详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • MySQL的主从复制原理详细分析

    MySQL的主从复制原理详细分析

    这篇文章主要介绍了MySQL的主从复制原理详细分析,读写分离是基于主从复制来实现的。文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • MySQL主从复制配置心跳功能介绍

    MySQL主从复制配置心跳功能介绍

    这篇文章主要介绍了MySQL主从复制配置心跳功能介绍,解决Slave has read all relay log; waiting for the slave I/O thread to update it问题,需要的朋友可以参考下
    2014-06-06

最新评论