在Postgres中,一个查询需要读取多少个磁盘页面?

3

我想知道在运行单个 Postgres 查询时有多少页(包括表和索引,如果有的话)是从磁盘读取(而不是从缓存读取)的。更好的是,如果有任何方法可以从“EXPLAIN ANALYZE”中提取这些信息。

2个回答

5

当您添加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 的索引扫描而需要的。

但这并不能区分从磁盘读取和从操作系统/文件系统缓存中读取的数据。它只是将shared_buffers缓存分离出来。 - jjanes
2
我认为“从磁盘读取(而不是从缓存中读取)”指的是Postgres缓存。我没有在问题中看到文件系统缓存的提及。但是,无法从执行计划中获取该信息(我怀疑在不使用某些操作系统低级调试工具的情况下很难轻松获得该信息)。 - user330315

1

一个扩展程序旨在将真实的磁盘读取与FS缓存读取分开,但它似乎只提供聚合数据,就像pg_stat_statements一样,而不是像EXPLAIN(ANALYZE,BUFFERS)那样提供单个执行。

您还可以使用set log_executor_stats TO on;,也许结合set client_min_messages TO log;来获取每次执行的顶级实际磁盘读取。然而,这里的用户体验相当粗糙。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接