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 блока бяха съхранени в кеша ("споделени буфери "), така че следващия път, когато са необходими, базата данни не трябва да ги чете (отново) от (бавния) твърд диск.
Когато стартирам отново този оператор, планът се променя на:
-> 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), вградена в компютъра и директно достъпна за процесора - за разлика от "външна памет".
Има няколко презентации за това как Postgres управлява споделените буфери:
- http://de.slideshare.net/EnterpriseDB/insidepostgresssharedmemory2015
- http://momjian.us/main/writings/pgsql/hw_performance/
- https://2ndquadrant.com/media/pdfs/talks/InsideBufferCache. pdf (много технически)
- http://raghavt.blogspot.de/2012/ 04/caching-in-postgresql.html