我负责一个大型的PostgreSQL数据库,只有几十个表。我怀疑其中许多表从未访问过。
检查上次访问某个表的时间的最佳方法是什么?我想加入一个触发的DELETE
,INSERT
和UPDATE
,但我希望有一个更有效的方法。
我负责一个大型的PostgreSQL数据库,只有几十个表。我怀疑其中许多表从未访问过。
检查上次访问某个表的时间的最佳方法是什么?我想加入一个触发的DELETE
,INSERT
和UPDATE
,但我希望有一个更有效的方法。
Answers:
pg_catalog.pg_statio_all_tables是你的朋友。您需要做的就是定期轮询pg_statio_all_tables以查看有问题的表。更改的统计信息〜活动表,未更改的统计信息〜可能未使用的表。请注意,select pg_stat_reset () ;
在监视过程中没有人会执行此操作。
例如:
test_1=# create table test_stats (col1 integer);
CREATE TABLE
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 0 | 0 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
插入:
test_1=# insert into test_stats (col1) select generate_series( 1, 10000000);
INSERT 0 10000000
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 44260 | 10088481 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
选择:
test_1=# select count (*) from test_stats where col1 between 10000 and 50000;
count
-------
40001
(1 row)
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 85560 | 10091429 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
删除:
test_1=# delete from test_stats where col1 between 10000 and 50000;
DELETE 40001
test_1=# select * from pg_catalog.pg_statio_all_tables
where schemaname not in ('pg_catalog', 'information_schema')
and relname = 'test_stats';
relid | schemaname | relname | heap_blks_read | heap_blks_hit | idx_blks_read | idx_blks_hit | toast_blks_read | toast_blks_hit | tidx_blks_read | tidx_blks_hit
-------+------------+------------+----------------+---------------+---------------+--------------+-----------------+----------------+----------------+---------------
22957 | public | test_stats | 155075 | 10136163 | [null] | [null] | [null] | [null] | [null] | [null]
(1 row)
update-- 2011-09-01
进一步的测试表明,vacuum
似乎在某种程度上增加了pg_statio_all_tables中的值,这对于您的期望使用是不幸的。虽然vacuum
不会无用的使用pg_statio_all_tables,但确实会使解释结果变得更加模糊。
也许最好监视的地方是pg_catalog.pg_stat_all_tables(至少在较新的Pg版本中)。我正在查看8.4版本,其中包含插入,读取,更新和删除的元组的计数-ISTR 8.2并没有全部功能,我也不知道8.3,所以YMMV取决于您所使用的Pg的版本使用。
第三个选项(用于插入,更新和删除活动)是查看$ PGDATA / base / $ datid目录中的文件时间戳。文件名应该映射到表的oid,因此您可以使用它来标识没有插入,更新或删除的表。不幸的是,这不能解决仍然要从中选择的表,并且使用表空间会引起其他问题(因为这些文件不会位于$ PGDATA / base / $ datid下)。直到刷新所有待处理的更改后,时间戳才会更新,但是如果文件在几个月内没有发生更改,那么当前待处理的更改的可能性可能很小。
select
。您是否考虑过记录?