postgreSQL中的共享命中缓存

St.*_*rio 11 sql postgresql caching

我正在尝试使用EXPLAIN命令并试图找出它是什么shared hit.

Seq Scan on foo  (cost=0.00..18334.00 rows=1000000 width=37) (actual time=0.030..90.500 rows=1000000 loops=1)
  Buffers: shared hit=512 read=7822
Total runtime: 116.080 ms
Run Code Online (Sandbox Code Playgroud)

我注意到,我们拥有的共享命中数越多,执行查询的速度就越快.但那是什么?就我而言,shared read只是从物理存储中读取RAID或者SSD.但为什么shared hit速度更快?它存储在RAM内还是哪里?

a_h*_*ame 15

shared hit 本质上意味着该值已经缓存在计算机的主存储器中,并且没有必要从硬盘读取它.

访问主存储器(RAM)是比从硬盘读取值更快.这就是为什么查询越快,共享命中率就越高.

在启动Postgres之后,主存储器(RAM)中没有任何数据可用,并且所有内容都需要从硬盘读取.

从执行计划中考虑此步骤:

  ->  Seq Scan on products.product_price  (cost=0.00..3210.27 rows=392273 width=0) (actual time=0.053..103.958 rows=392273 loops=1)
        Output: product_id, valid_from, valid_to, price
        Buffers: shared read=2818
        I/O Timings: read=48.382
Run Code Online (Sandbox Code Playgroud)

"缓冲区:共享读取= 2818"部分意味着必须从硬盘读取2818个块(每个8k)(这需要48ms - 我有一个SSD).这些2818块存储在缓存中(" 共享缓冲区 "),以便下次需要时,数据库不需要(再次)从(慢速)硬盘读取它们.

当我重新运行该语句时,计划将更改为:

  ->  Seq Scan on products.product_price  (cost=0.00..3210.27 rows=392273 width=0) (actual time=0.012..45.690 rows=392273 loops=1)
        Output: product_id, valid_from, valid_to, price
        Buffers: shared hit=2818
Run Code Online (Sandbox Code Playgroud)

这意味着那些2818阻塞了前一个语句仍在主内存(= RAM)中,而Postgres不需要从硬盘中读取它们.

"内存"总是指内置于计算机中并可直接访问CPU的主内存(RAM) - 而不是"外部存储".

有关Postgres如何管理共享缓冲区的几个演示文稿:

  • @soung:这就是 [pg_prewarm](https://www.postgresql.org/docs/current/pgprewarm.html) 的用途。 (2认同)