F.31. pgstattuple
Thepgstattuple module provides various functions to obtain tuple-level statistics.
As these functions return detailed page-level information, only the superuser has EXECUTE privileges on them upon installation. After the functions have been installed, users may issueGRANT commands to change the privileges on the functions to allow non-superusers to execute them. Members of thepg_stat_scan_tables role are granted access by default. See the description of theGRANT command for specifics.
F.31.1. Functions
pgstattuple(regclass) returns recordpgstattuplereturns a relation's physical length, percentage of“dead” tuples, and other info. This may help users to determine whether vacuum is necessary or not. The argument is the target relation's name (optionally schema-qualified) or OID. For example:test=> SELECT * FROM pgstattuple('pg_catalog.pg_proc');-[ RECORD 1 ]------+-------table_len | 458752tuple_count | 1470tuple_len | 438896tuple_percent | 95.67dead_tuple_count | 11dead_tuple_len | 3157dead_tuple_percent | 0.69free_space | 8932free_percent | 1.95The output columns are described inTable F.23.
Table F.23.
pgstattupleOutput ColumnsColumn Type Description table_lenbigintPhysical relation length in bytes tuple_countbigintNumber of live tuples tuple_lenbigintTotal length of live tuples in bytes tuple_percentfloat8Percentage of live tuples dead_tuple_countbigintNumber of dead tuples dead_tuple_lenbigintTotal length of dead tuples in bytes dead_tuple_percentfloat8Percentage of dead tuples free_spacebigintTotal free space in bytes free_percentfloat8Percentage of free space Note
The
table_lenwill always be greater than the sum of thetuple_len,dead_tuple_lenandfree_space. The difference is accounted for by fixed page overhead, the per-page table of pointers to tuples, and padding to ensure that tuples are correctly aligned.pgstattupleacquires only a read lock on the relation. So the results do not reflect an instantaneous snapshot; concurrent updates will affect them.pgstattuplejudges a tuple is“dead” ifHeapTupleSatisfiesDirtyreturns false.pgstattuple(text) returns recordThis is the same as
pgstattuple(regclass), except that the target relation is specified as TEXT. This function is kept because of backward-compatibility so far, and will be deprecated in some future release.pgstatindex(regclass) returns recordpgstatindexreturns a record showing information about a B-tree index. For example:test=> SELECT * FROM pgstatindex('pg_cast_oid_index');-[ RECORD 1 ]------+------version | 2tree_level | 0index_size | 16384root_block_no | 1internal_pages | 0leaf_pages | 1empty_pages | 0deleted_pages | 0avg_leaf_density | 54.27leaf_fragmentation | 0The output columns are:
Column Type Description versionintegerB-tree version number tree_levelintegerTree level of the root page index_sizebigintTotal index size in bytes root_block_nobigintLocation of root page (zero if none) internal_pagesbigintNumber of“internal” (upper-level) pages leaf_pagesbigintNumber of leaf pages empty_pagesbigintNumber of empty pages deleted_pagesbigintNumber of deleted pages avg_leaf_densityfloat8Average density of leaf pages leaf_fragmentationfloat8Leaf page fragmentation The reported
index_sizewill normally correspond to one more page than is accounted for byinternal_pages + leaf_pages + empty_pages + deleted_pages, because it also includes the index's metapage.As with
pgstattuple, the results are accumulated page-by-page, and should not be expected to represent an instantaneous snapshot of the whole index.pgstatindex(text) returns recordThis is the same as
pgstatindex(regclass), except that the target index is specified as TEXT. This function is kept because of backward-compatibility so far, and will be deprecated in some future release.pgstatginindex(regclass) returns recordpgstatginindexreturns a record showing information about a GIN index. For example:test=> SELECT * FROM pgstatginindex('test_gin_index');-[ RECORD 1 ]--+--version | 1pending_pages | 0pending_tuples | 0The output columns are:
Column Type Description versionintegerGIN version number pending_pagesintegerNumber of pages in the pending list pending_tuplesbigintNumber of tuples in the pending list pgstathashindex(regclass) returns recordpgstathashindexreturns a record showing information about a HASH index. For example:test=> select * from pgstathashindex('con_hash_index');-[ RECORD 1 ]--+-----------------version | 4bucket_pages | 33081overflow_pages | 0bitmap_pages | 1unused_pages | 32455live_items | 10204006dead_items | 0free_percent | 61.8005949100872The output columns are:
Column Type Description versionintegerHASH version number bucket_pagesbigintNumber of bucket pages overflow_pagesbigintNumber of overflow pages bitmap_pagesbigintNumber of bitmap pages unused_pagesbigintNumber of unused pages live_itemsbigintNumber of live tuples dead_tuplesbigintNumber of dead tuples free_percentfloatPercentage of free space pg_relpages(regclass) returns bigintpg_relpagesreturns the number of pages in the relation.pg_relpages(text) returns bigintThis is the same as
pg_relpages(regclass), except that the target relation is specified as TEXT. This function is kept because of backward-compatibility so far, and will be deprecated in some future release.pgstattuple_approx(regclass) returns recordpgstattuple_approxis a faster alternative topgstattuplethat returns approximate results. The argument is the target relation's name or OID. For example:test=> SELECT * FROM pgstattuple_approx('pg_catalog.pg_proc'::regclass);-[ RECORD 1 ]--------+-------table_len | 573440scanned_percent | 2approx_tuple_count | 2740approx_tuple_len | 561210approx_tuple_percent | 97.87dead_tuple_count | 0dead_tuple_len | 0dead_tuple_percent | 0approx_free_space | 11996approx_free_percent | 2.09The output columns are described inTable F.24.
Whereas
pgstattuplealways performs a full-table scan and returns an exact count of live and dead tuples (and their sizes) and free space,pgstattuple_approxtries to avoid the full-table scan and returns exact dead tuple statistics along with an approximation of the number and size of live tuples and free space.It does this by skipping pages that have only visible tuples according to the visibility map (if a page has the corresponding VM bit set, then it is assumed to contain no dead tuples). For such pages, it derives the free space value from the free space map, and assumes that the rest of the space on the page is taken up by live tuples.
For pages that cannot be skipped, it scans each tuple, recording its presence and size in the appropriate counters, and adding up the free space on the page. At the end, it estimates the total number of live tuples based on the number of pages and tuples scanned (in the same way that VACUUM estimates pg_class.reltuples).
Table F.24.
pgstattuple_approxOutput ColumnsColumn Type Description table_lenbigintPhysical relation length in bytes (exact) scanned_percentfloat8Percentage of table scanned approx_tuple_countbigintNumber of live tuples (estimated) approx_tuple_lenbigintTotal length of live tuples in bytes (estimated) approx_tuple_percentfloat8Percentage of live tuples dead_tuple_countbigintNumber of dead tuples (exact) dead_tuple_lenbigintTotal length of dead tuples in bytes (exact) dead_tuple_percentfloat8Percentage of dead tuples approx_free_spacebigintTotal free space in bytes (estimated) approx_free_percentfloat8Percentage of free space In the above output, the free space figures may not match the
pgstattupleoutput exactly, because the free space map gives us an exact figure, but is not guaranteed to be accurate to the byte.
F.31.2. Authors
Tatsuo Ishii, Satoshi Nagayasu and Abhijit Menon-Sen