MySQL的Query?Cache和PostgreSQL的pg_prewarm詳解
MySQL 的 Query CachePostgreSQL 的 pg_prewarm核心功能、原理機(jī)制、使用建議、適用場(chǎng)景、對(duì)比分析
一、MySQL 的 Query Cache(查詢緩存)【已廢棄】
功能概述
MySQL 的 Query Cache 是一個(gè)用于緩存 SQL 查詢結(jié)果的全局緩存,當(dāng)完全相同的 SQL 被再次執(zhí)行時(shí),可以直接返回緩存結(jié)果,跳過解析、優(yōu)化、執(zhí)行流程。
原理機(jī)制
- 查詢緩存的是 結(jié)果集(Result Set),不是執(zhí)行計(jì)劃。
- 只有完全相同的 SQL 字符串(包括空格、大小寫)才能命中緩存。
- 當(dāng)表中的數(shù)據(jù)發(fā)生變化(如
INSERT/UPDATE/DELETE),該表相關(guān)的緩存會(huì)全部失效。 - Query Cache 是全局唯一的,不分庫表、用戶,也不是線程局部緩存。
主要參數(shù):
query_cache_type = 1 # 0=off, 1=on, 2=DEMAND query_cache_size = 64M # 緩存總大小 query_cache_limit = 1M # 單條查詢最大緩存
優(yōu)缺點(diǎn):
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 小型、讀多寫少場(chǎng)景命中率高,減少 CPU 和磁盤壓力 | 易導(dǎo)致全局鎖爭(zhēng)用,數(shù)據(jù)一變即清空相關(guān)緩存,命中率低 |
| 查詢速度可極大提升(只要 SQL 和表數(shù)據(jù)都未變化) | 高并發(fā)寫時(shí)性能下降嚴(yán)重,適得其反;多核擴(kuò)展性差 |
注意事項(xiàng):
- MySQL 5.7 開始默認(rèn)關(guān)閉,8.0 已完全移除(廢棄)。
- 在現(xiàn)代系統(tǒng)中,推薦使用應(yīng)用層緩存(如 Redis)、Proxy 層緩存或使用 InnoDB Buffer Pool(頁緩存)而非 Query Cache。
二、PostgreSQL 的 pg_prewarm(頁級(jí)預(yù)熱)
功能概述
PostgreSQL 的 pg_prewarm 是一個(gè) 將表或索引數(shù)據(jù)加載進(jìn)共享緩沖區(qū)(shared_buffers) 的擴(kuò)展模塊,常用于數(shù)據(jù)庫重啟后的 熱數(shù)據(jù)預(yù)加載(預(yù)熱),加快數(shù)據(jù)庫“恢復(fù)訪問性能”。
原理機(jī)制
- PostgreSQL 使用 Buffer Pool(共享緩沖區(qū)) 管理數(shù)據(jù)頁,冷啟動(dòng)時(shí)緩存為空。
pg_prewarm可以將指定的表、索引頁主動(dòng)讀取進(jìn)緩存,避免冷啟動(dòng)時(shí)慢查詢。- 可以搭配
auto_preload_libraries自動(dòng)在啟動(dòng)時(shí)加載,也可以定期 dump 熱頁信息并在啟動(dòng)恢復(fù)。
使用方式
-- 加載擴(kuò)展
CREATE EXTENSION IF NOT EXISTS pg_prewarm;
-- 手動(dòng)預(yù)熱某表
SELECT pg_prewarm('mytable');
-- 指定預(yù)熱方式(可選:prefetch, read, buffer, read_async)
SELECT pg_prewarm('mytable', 'prefetch');
配合自動(dòng)預(yù)熱使用
- 開啟插件:
shared_preload_libraries = 'pg_prewarm'
- 使用
pg_buffercache+pg_prewarm定期導(dǎo)出熱數(shù)據(jù)頁,在重啟后恢復(fù):
SELECT * FROM pg_buffercache LIMIT 10; -- 使用 extension 來結(jié)合自動(dòng)恢復(fù)機(jī)制
優(yōu)缺點(diǎn):
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 明確、主動(dòng)地提升關(guān)鍵數(shù)據(jù)表冷啟動(dòng)性能 | 非自動(dòng)緩存,需額外維護(hù)策略與腳本 |
| 適合大表/索引重啟預(yù)熱,提升系統(tǒng)恢復(fù)性能 | 如果 shared_buffers 太小,效果有限 |
三、對(duì)比總結(jié)
| 特性 / 系統(tǒng) | MySQL Query Cache | PostgreSQL pg_prewarm |
|---|---|---|
| 緩存內(nèi)容 | SQL 查詢結(jié)果 | 數(shù)據(jù)頁(blocks) |
| 緩存粒度 | SQL 層 | 存儲(chǔ)層(頁級(jí)別) |
| 命中條件 | SQL 完全相同且數(shù)據(jù)未改動(dòng) | 無需精確 SQL,可按表預(yù)熱 |
| 一致性影響 | 高(數(shù)據(jù)更新后清除緩存) | 無影響(數(shù)據(jù)頁始終一致) |
| 是否自動(dòng) | 可自動(dòng)緩存 | 需手動(dòng)或腳本維護(hù) |
| 現(xiàn)代支持情況 | MySQL 8.0 移除 | PostgreSQL 官方推薦擴(kuò)展 |
| 推薦替代方案 | Redis 緩存 + InnoDB Buffer Pool | 使用 shared_buffers + pg_prewarm |
實(shí)戰(zhàn)建議
若你是運(yùn)維/PostgreSQL DBA
建議使用 pg_prewarm 結(jié)合 pg_buffercache、監(jiān)控?zé)犴撛L問模式,定期導(dǎo)出熱數(shù)據(jù)頁信息,并寫入 cron 腳本,在系統(tǒng)重啟后調(diào)用預(yù)熱腳本提升性能。
若你還在使用老版本 MySQL(5.6/5.7)
避免啟用 Query Cache(除非是非常小的讀密集型場(chǎng)景),建議通過應(yīng)用層緩存 + InnoDB 參數(shù)優(yōu)化提升查詢效率。
- 使用 InnoDB 緩沖池預(yù)熱:
innodb_buffer_pool_dump_at_shutdown = 1 innodb_buffer_pool_load_at_startup = 1
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Mysql 日期時(shí)間 DATE_FORMAT(date,format)
Mysql 日期時(shí)間 DATE_FORMAT(date,format) ,需要的朋友可以參考下。2010-12-12
MySQL事務(wù)與隔離級(jí)別的使用基礎(chǔ)理論
這篇文章主要介紹了MySQL事務(wù)的隔離級(jí)別詳情,事務(wù)隔離級(jí)別越高,為避免沖突所花費(fèi)的性能也就越多,即效率低。在“可重復(fù)讀”級(jí)別,實(shí)際上可以解決部分的虛讀問題,但是不能防止update更新產(chǎn)生的虛讀問題,要禁止虛讀產(chǎn)生,還是需要設(shè)置串行化隔離級(jí)別2023-02-02
MySQL插入數(shù)據(jù)與查詢數(shù)據(jù)
這篇文章主要介紹了 MySQL插入數(shù)據(jù)與查詢數(shù)據(jù),缺省插入、缺省插入、缺省插入等各種數(shù)據(jù)插入分享,需要的小伙伴可以參考一下,希望對(duì)你有所幫助2022-03-03
linux下mysql開啟遠(yuǎn)程訪問權(quán)限 防火墻開放3306端口
這篇文章主要為大家詳細(xì)介紹了linux下mysql開啟遠(yuǎn)程訪問權(quán)限,防火墻開放3306端口,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
MySQL存儲(chǔ)數(shù)據(jù)亂碼的問題解析
這篇文章主要介紹了MySQL存儲(chǔ)數(shù)據(jù)亂碼的問題解析,作者從實(shí)際使用中的多個(gè)方面定位其原因然后解決,需要的朋友可以參考下2015-05-05
Mysql遷移到TiDB雙寫數(shù)據(jù)庫兜底方案詳解
這篇文章主要為大家介紹了Mysql遷移到TiDB雙寫數(shù)據(jù)庫兜底方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01

