PostgreSQL 如何「霸佔」系統OS cache 提升查詢性能
- 2019 年 11 月 10 日
- 筆記
上期回答了關於PG數據庫緩存和系統的緩存之間的一些關係,其中可能有有一些可以在討論的問題,既然數據庫可以「黏住」常用的數據,那系統的緩存我們還是否可以繼續利用,還是僅僅拿他當一個所謂的「二級緩存」(這個詞可能不嚴謹)來使用。
今天我們就來說說一個PG的擴展 pgfincore 讓這個擴展來為我們更完善相關的服務和緩存狀態的展示,pgfincore是2ndQuadrant 公司,一家專門為的開源插件。

安裝的過程就不說了,非常的簡單,make&make install , create extension pgfincore
下面其他的先不講,先看這個插件能幫助我們做些什麼,在講其他的。
下圖很清楚的顯示了,一個300萬行的表在系統中經歷了2次 count的操作大致使用的時間,按照一般的數據庫系統來說,我第一次查詢和第二次查詢如果查詢語句是一致的,那第二次的速度應該比第一次快,因為我緩存了查詢的語句和結果之間的對應關係(當然這裡也有其他的情況,不在展開)。
圖中我們使用pgfincore插件中的一個,將表或索引預裝入到OS 緩存層面的功能,我們再次查詢,發現比第二次的速度還快,僅僅300萬的數據使用82毫秒。這說明我們將表或索引提升至OS的緩存中,對查詢的加速是有效的嗎,即使我們用不上什麼索引,或沒有所以的情況下。

select * from pgsysconf();

通過pgsyusconf() 可以查看當前系統的OS 控制的頁面有多少,剩餘多少。在通過這個插件可以很清晰的指導,當然我們缺少不缺少系統OS層面的緩存。(缺不缺 OS 系統緩存的問題我們可以解決了)
當然我們通過
select * from pgfincore('test'); 可以看到一個表的DISK 與OS PAGE 之間的對應的關係,

下面做一個實驗來證明,加載和不加載OS 內存的情況下,到底有什麼區別,下圖中包含了15次頻繁的對一個表的 select * from 表 limit 10;的操作

總體的數據在0.6986秒
我們在加載了OS 系統緩存後,我們在做15次

顯示總體30次的查詢事假在0.9625秒,那加載後查詢的15次的時間是
0.9625 – 0.6986 = 0.2639 秒 也就是說大致節省了 3分之二2 強的時間。
另外在前幾期中講了pg_rewarm 插件,可以在系統重啟之後進行類似MYSQL的 將系統重啟動之前的數據灌入到INNODB BUFFER POOL中,但我們忽略了另一個問題,就是MYSQL 以及其他數據庫是沒有OS 緩存利用這麼一說的,所以POSTGRESQL 如果你在重啟後還可以考慮對部分數據,怎麼快速的緩衝到 OS 的緩衝的事情。實際上在做了幾個測試後,讓我打消了使用pgfadvise_loader的想法,因為提升到速度只在第一次有效,另外如果是生產機有多少機會會經常重啟,如果是測試機,有必要勞心勞力的作這個事情。
當然如果你感興趣可以看一下官方的文檔,關注一下 pgfadvise_loader可以滿足你嫉妒優化的想法。
下面整理了一下相關的一些命令
1 select * from pgsysconf_pretty();
得到你系統的OS層面的緩衝信息
2 select * from pgfadvise_willneed('表名');
加載索引或表到OS CACHE 層面
3 select * from pgfadvise_dontneed('p表名');
卸載表的內容從OS CACHE 層面