我尝试使用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
我注意到我们拥有的共享命中数越多,执行查询的速度就越快。但那是什么?据我所知,shared read
只是从RAID
或SSD
等物理存储中读取。但为什么shared hit
会更快?它存储在RAM内还是哪里?
答案 0 :(得分:13)
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
“缓冲区:共享读取= 2818”部分意味着必须从硬盘读取2818个块(每个8k)(这需要48ms - 我有一个SSD)。这些2818块存储在缓存中(“shared buffers”),以便下次需要时,数据库不需要(再次)从(慢速)硬盘中读取它们。
当我重新运行该声明时,计划将更改为:
-> 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
这意味着那些2818阻止前一个语句仍在主内存(= RAM)中,而Postgres不需要从硬盘中读取它们。
“内存”总是指计算机内置的主存储器(RAM),可直接由CPU访问 - 而不是“外部存储”。
关于Postgres如何管理共享缓冲区有几个演示文稿: