MySQL的Query?Cache和PostgreSQL的pg_prewarm詳解
MySQL 的 Query CachePostgreSQL 的 pg_prewarm核心功能、原理機(jī)制、使用建議、適用場景、對比分析
一、MySQL 的 Query Cache(查詢緩存)【已廢棄】
功能概述
MySQL 的 Query Cache 是一個用于緩存 SQL 查詢結(jié)果的全局緩存,當(dāng)完全相同的 SQL 被再次執(zhí)行時,可以直接返回緩存結(jié)果,跳過解析、優(yōu)化、執(zhí)行流程。
原理機(jī)制
- 查詢緩存的是 結(jié)果集(Result Set),不是執(zhí)行計(jì)劃。
- 只有完全相同的 SQL 字符串(包括空格、大小寫)才能命中緩存。
- 當(dāng)表中的數(shù)據(jù)發(fā)生變化(如
INSERT/UPDATE/DELETE),該表相關(guān)的緩存會全部失效。 - 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) |
|---|---|
| 小型、讀多寫少場景命中率高,減少 CPU 和磁盤壓力 | 易導(dǎo)致全局鎖爭用,數(shù)據(jù)一變即清空相關(guān)緩存,命中率低 |
| 查詢速度可極大提升(只要 SQL 和表數(shù)據(jù)都未變化) | 高并發(fā)寫時性能下降嚴(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(頁級預(yù)熱)
功能概述
PostgreSQL 的 pg_prewarm 是一個 將表或索引數(shù)據(jù)加載進(jìn)共享緩沖區(qū)(shared_buffers) 的擴(kuò)展模塊,常用于數(shù)據(jù)庫重啟后的 熱數(shù)據(jù)預(yù)加載(預(yù)熱),加快數(shù)據(jù)庫“恢復(fù)訪問性能”。
原理機(jī)制
- PostgreSQL 使用 Buffer Pool(共享緩沖區(qū)) 管理數(shù)據(jù)頁,冷啟動時緩存為空。
pg_prewarm可以將指定的表、索引頁主動讀取進(jìn)緩存,避免冷啟動時慢查詢。- 可以搭配
auto_preload_libraries自動在啟動時加載,也可以定期 dump 熱頁信息并在啟動恢復(fù)。
使用方式
-- 加載擴(kuò)展
CREATE EXTENSION IF NOT EXISTS pg_prewarm;
-- 手動預(yù)熱某表
SELECT pg_prewarm('mytable');
-- 指定預(yù)熱方式(可選:prefetch, read, buffer, read_async)
SELECT pg_prewarm('mytable', 'prefetch');
配合自動預(yù)熱使用
- 開啟插件:
shared_preload_libraries = 'pg_prewarm'
- 使用
pg_buffercache+pg_prewarm定期導(dǎo)出熱數(shù)據(jù)頁,在重啟后恢復(fù):
SELECT * FROM pg_buffercache LIMIT 10; -- 使用 extension 來結(jié)合自動恢復(fù)機(jī)制
優(yōu)缺點(diǎn):
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 明確、主動地提升關(guān)鍵數(shù)據(jù)表冷啟動性能 | 非自動緩存,需額外維護(hù)策略與腳本 |
| 適合大表/索引重啟預(yù)熱,提升系統(tǒng)恢復(fù)性能 | 如果 shared_buffers 太小,效果有限 |
三、對比總結(jié)
| 特性 / 系統(tǒng) | MySQL Query Cache | PostgreSQL pg_prewarm |
|---|---|---|
| 緩存內(nèi)容 | SQL 查詢結(jié)果 | 數(shù)據(jù)頁(blocks) |
| 緩存粒度 | SQL 層 | 存儲層(頁級別) |
| 命中條件 | SQL 完全相同且數(shù)據(jù)未改動 | 無需精確 SQL,可按表預(yù)熱 |
| 一致性影響 | 高(數(shù)據(jù)更新后清除緩存) | 無影響(數(shù)據(jù)頁始終一致) |
| 是否自動 | 可自動緩存 | 需手動或腳本維護(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(除非是非常小的讀密集型場景),建議通過應(yīng)用層緩存 + InnoDB 參數(shù)優(yōu)化提升查詢效率。
- 使用 InnoDB 緩沖池預(yù)熱:
innodb_buffer_pool_dump_at_shutdown = 1 innodb_buffer_pool_load_at_startup = 1
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql導(dǎo)入導(dǎo)出數(shù)據(jù)的示例詳解
本文主要介紹了MySQL 導(dǎo)出和導(dǎo)入數(shù)據(jù)的幾種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-05-05
mysql查詢結(jié)果實(shí)現(xiàn)多列拼接查詢
本文主要介紹了mysql查詢結(jié)果實(shí)現(xiàn)多列拼接查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04

