shared hit
essencialmente significa que o valor já foi armazenado em cache na memória principal do computador e não foi necessário lê-lo do disco rígido. O acesso à memória principal (RAM) é muito mais rápido do que a leitura de valores do disco rígido. E é por isso que a consulta é mais rápida quanto mais hits de compartilhamento ela tiver.
Imediatamente após iniciar o Postgres, nenhum dos dados está disponível na memória principal (RAM) e tudo precisa ser lido do disco rígido.
Considere esta etapa de um plano de execução:
-> 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
A parte "Buffers:shared read=2818" significa que 2818 blocos (cada 8k) tiveram que ser lidos do disco rígido (e isso levou 48ms - eu tenho um SSD). Esses 2.818 blocos foram armazenados no cache (o "buffers compartilhados ") para que na próxima vez que forem necessários, o banco de dados não precise lê-los (novamente) do disco rígido (lento).
Quando eu reexecuto essa instrução, o plano muda para:
-> 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
O que significa que aqueles 2818 blocos que a declaração anterior ainda estavam na memória principal (=RAM) e o Postgres não precisava lê-los do disco rígido.
"memória" sempre se refere à memória principal (RAM) embutida no computador e diretamente acessível à CPU - em oposição a "armazenamento externo".
Existem várias apresentações sobre como o Postgres gerencia os buffers compartilhados:
- http://de.slideshare.net/EnterpriseDB/insidepostgressharedmemory2015
- http://momjian.us/main/writings/pgsql/hw_performance/
- https://2ndquadrant.com/media/pdfs/talks/InsideBufferCache. pdf (muito técnico)
- http://raghavt.blogspot.de/2012/ 04/caching-in-postgresql.html