Postgresql 性能 - 索引页面命中率
Postgresql performance - Index page hits
我运行以下查询估计从内存读取的索引页(缓冲区命中)与从磁盘读取的索引页的比率
select
t.schemaname,
t.relname as "Table Name",
io_i.indexrelname as "Index Name",
case when (io_i.idx_blks_hit <> 0 or io_i.idx_blks_read <> 0) then
round(io_i.idx_blks_hit/(io_i.idx_blks_hit::numeric +
io_i.idx_blks_read::numeric), 4) else null end as "Index Hit Ratio"
from
pg_stat_user_tables t
join pg_statio_user_indexes io_i on io_i.relid = t.relid
order by "Index Hit Ratio" desc;
而且我有几个指标这个比率太低(低于 0.7)。
请告知可能是什么原因以及如何改进。
shared_buffers
不够大,无法包含所有索引,因此查询会命中磁盘(或文件系统缓存,这没问题)。
可能是因为这些索引不经常使用,所以 PostgreSQL 不缓存它们是有道理的。检查 pg_stat_user_indexes
视图中的 idx_scan
以查看自上次统计信息重置以来扫描索引的频率。
如果您可以将 shared_buffers
设置得足够高以包含整个数据库,请这样做。否则,read the manual 对设置 shared_buffers
.
有一些建议
除此之外,只要性能好,I/O系统不超载,我什么都不做。如果遇到问题,请尝试获取更多 RAM。如果该选项已用尽,请获得更快的存储空间。
我运行以下查询估计从内存读取的索引页(缓冲区命中)与从磁盘读取的索引页的比率
select
t.schemaname,
t.relname as "Table Name",
io_i.indexrelname as "Index Name",
case when (io_i.idx_blks_hit <> 0 or io_i.idx_blks_read <> 0) then
round(io_i.idx_blks_hit/(io_i.idx_blks_hit::numeric +
io_i.idx_blks_read::numeric), 4) else null end as "Index Hit Ratio"
from
pg_stat_user_tables t
join pg_statio_user_indexes io_i on io_i.relid = t.relid
order by "Index Hit Ratio" desc;
而且我有几个指标这个比率太低(低于 0.7)。 请告知可能是什么原因以及如何改进。
shared_buffers
不够大,无法包含所有索引,因此查询会命中磁盘(或文件系统缓存,这没问题)。
可能是因为这些索引不经常使用,所以 PostgreSQL 不缓存它们是有道理的。检查 pg_stat_user_indexes
视图中的 idx_scan
以查看自上次统计信息重置以来扫描索引的频率。
如果您可以将 shared_buffers
设置得足够高以包含整个数据库,请这样做。否则,read the manual 对设置 shared_buffers
.
除此之外,只要性能好,I/O系统不超载,我什么都不做。如果遇到问题,请尝试获取更多 RAM。如果该选项已用尽,请获得更快的存储空间。