开发者

is there a way to get postgres show actual i/o for query

I know that with EXPLAIN ANALYZE I can get the predicted cost and actual execution times (which are in different units, argh!), but is there a way to get Postgres to tell me how much I/O (logical or physical) that it has to do to satisfy a query?

(I'm looking for the equivalent of "set statistics io on开发者_如何学JAVA" for Sybase or MS SQL Server.)


Starting in PostgreSQL 9.0, you can execute:

EXPLAIN (ANALYZE ON, BUFFERS ON) SELECT ...

And it will show you how the statement interacted with PostgreSQL's cache. In cases where this reports a cache miss, that's going to be an OS call to read something. You can't be sure that's a physical I/O, because it may be in the OS cache. But this is probably more like what you're looking for here than trying to look at the pg_stat_* information.


This answer is not related directly to a specific query statement, but for helping those who ended here when searching for a way of showing a "disk vs cache":

-- perform a "select pg_stat_reset();" when you want to reset counter statistics
with 
all_tables as
(
SELECT  *
FROM    (
    SELECT  'all'::text as table_name, 
        sum( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk, 
        sum( (coalesce(heap_blks_hit,0)  + coalesce(idx_blks_hit,0)  + coalesce(toast_blks_hit,0)  + coalesce(tidx_blks_hit,0))  ) as from_cache    
    FROM    pg_statio_all_tables  --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
    ) a
WHERE   (from_disk + from_cache) > 0 -- discard tables without hits
),
tables as 
(
SELECT  *
FROM    (
    SELECT  relname as table_name, 
        ( (coalesce(heap_blks_read,0) + coalesce(idx_blks_read,0) + coalesce(toast_blks_read,0) + coalesce(tidx_blks_read,0)) ) as from_disk, 
        ( (coalesce(heap_blks_hit,0)  + coalesce(idx_blks_hit,0)  + coalesce(toast_blks_hit,0)  + coalesce(tidx_blks_hit,0))  ) as from_cache    
    FROM    pg_statio_all_tables --> change to pg_statio_USER_tables if you want to check only user tables (excluding postgres's own tables)
    ) a
WHERE   (from_disk + from_cache) > 0 -- discard tables without hits
)
SELECT  table_name as "table name",
    from_disk as "disk hits",
    round((from_disk::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% disk hits",
    round((from_cache::numeric / (from_disk + from_cache)::numeric)*100.0,2) as "% cache hits",
    (from_disk + from_cache) as "total hits"
FROM    (SELECT * FROM all_tables UNION ALL SELECT * FROM tables) a
ORDER   BY (case when table_name = 'all' then 0 else 1 end), from_disk desc

is there a way to get postgres show actual i/o for query


There isn't anything as simple as a SET STATISTICS IO ON for PostgreSQL, unfortunately. There are, however, IO stats available via the pg_statio_* system catalogs. It's not perfect since the data isn't scoped to a session, but if you're looking to see how efficient queries are and are in a clean room environment, it works well enough for most problems.

http://www.postgresql.org/docs/current/static/monitoring-stats.html


Not really as PostgreSQL also relies heavily on the OS cache and it has no way of knowing what's going on there. The pg_statio* family of views in pg_catalog keeps running counts of hits and actual reads but those reads might have hit the OS cache.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜