2011-06-02 98 views
7

我知道使用EXPLAIN ANALYZE我可以得到預計的成本和實際執行時間(它們是不同的單位,啊!),但有沒有辦法讓Postgres告訴我它需要做多少I/O(邏輯或物理)來滿足查詢?有沒有辦法讓postgres顯示實際的I/O查詢

(我在尋找相當於「組統計木衛一」爲Sybase或MS SQL Server)。

回答

9

在PostgreSQL的9.0開始,你可以執行:

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

,它會告訴你該語句與PostgreSQL的緩存如何相互作用。在報告緩存未命中的情況下,這將是一次操作系統調用以讀取某些內容。你不能確定這是一個物理I/O,因爲它可能在OS緩存中。但這可能更像你在這裏尋找的東西,而不是試圖查看pg_stat_ *信息。

1

有沒有什麼簡單的SET STATISTICS IO ONPostgreSQL,很遺憾。但是,通過pg_statio_*系統目錄可以獲得IO統計信息。這並不完美,因爲數據不在會話範圍內,但如果您希望查看高效查詢的效果並處於無塵室環境,那麼對於大多數問題來說,這種方法足夠好。

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

1

不是真的如PostgreSQL的也很大程度上依賴於操作系統的緩存,它沒有辦法知道發生了什麼事情在那裏的方式。 pg_catalog中的pg_statio *系列視圖保持運行計數的命中和實際讀取,但這些讀取可能已經命中了操作系統緩存。

8

這個答案是沒有直接關係到一個特定的查詢語句,但對於幫助那些誰尋求呈現出「磁盤緩存VS」的方式,當在這裏結束:

-- 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 

enter image description here

相關問題