Я хотел бы знать, сколько страниц (таблица + индекс, если есть) считываются с диска (а не из кеша) при выполнении одного запроса Postgres. Еще лучше, если есть способ извлечь эту информацию из EXPLAIN ANALYZE.
Эта информация доступна, когда вы добавляете опцию buffers
: explain (analyze, buffers) select ...
например
explain (analyze, buffers)
select *
from salaries s
join employees e on e.emp_no = s.emp_no
where s.emp_no in ('10001', '20001', '30001', '40001', '50001', '99999', '99996');
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.85..1016.67 rows=81 width=51) (actual time=0.152..18.530 rows=96 loops=1)
Buffers: shared hit=407 read=5
I/O Timings: read=15.340
-> Index Scan using salaries_pkey on salaries s (cost=0.43..349.03 rows=81 width=20) (actual time=0.082..0.332 rows=96 loops=1)
Index Cond: ((emp_no)::text = ANY ('{10001,20001,30001,40001,50001,99999,99996}'::text[]))
Buffers: shared hit=28
-> Index Scan using employees_pkey on employees e (cost=0.42..8.24 rows=1 width=31) (actual time=0.187..0.187 rows=1 loops=96)
Index Cond: ((emp_no)::text = (s.emp_no)::text)
Buffers: shared hit=379 read=5
I/O Timings: read=15.340
Planning Time: 256.640 ms
Execution Time: 18.628 ms
Вы можете видеть, что всего потребовалось 412 страниц (= блоков). 5 из них должны были быть получены из файловой системы ("read=5") - эти 5 были необходимы из-за сканирования индекса на employees_pkey
Я предположил, что «читаются с диска (а не из кеша)» относятся к кешу Postgres. Я не вижу кеш файловой системы, упомянутый в вопросе. Но получить эту информацию из плана выполнения будет невозможно (и я сомневаюсь, что это легко возможно без использования некоторых инструментов отладки низкого уровня для операционной системы)
Существует расширение, которое должно отделять истинные чтения с диска от чтения кеша FS, но, похоже, оно предоставляет данные только в совокупности, как это делает pg_stat_statements, а не в отдельных исполнениях, как это делает EXPLAIN (ANALYZE, BUFFERS).
Вы также можете использовать set log_executor_stats TO on;
, возможно, в сочетании с set client_min_messages TO log;
, чтобы получить фактические чтения с диска верхнего уровня для каждого выполнения. Однако пользовательский опыт здесь довольно грубый.
Но это не отличает чтение с диска от чтения из кеша ОС/ФС. Он выделяет только кеш shared_buffers.