Table size with page layout

依然范特西╮ 提交于 2019-12-30 05:14:06

问题


I'm using PostgreSQL 9.2 on Oracle Linux Server release 6.3.

According to the storage layout documentation, a page layout holds:

  • PageHeaderData(24 byte)
  • n number of points to item(index item / table item) AKA ItemIdData(4 byte)
  • free space
  • n number of items
  • special space

I tested it to make some formula to estimate table size anticipated...(TOAST concept might be ignored.)

postgres=# \d t1;

                      Table "public.t1"
    Column    ','         Type         ','         Modifiers
---------------+------------------------+------------------------------
 code          |character varying(8)    |not null
 name          |character varying(100)  |not null
 act_yn        |character(1)            |not null default 'N'::bpchar
 desc          |character varying(100)  |not null
 org_code1     |character varying(3)    |
 org_cole2     |character varying(10)   |

 postgres=# insert into t1 values(
'11111111', -- 8
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'Y',
'1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111', <-- 100
'111',
'1111111111');

postgres=# select * from pgstattuple('t1');
 table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
      8192 |           1 |       252 |          3.08 |                1 |            252 |               3.08 |       7644 |        93.31
(1 row)

Why is tuple_len 252 instead of 249? ("222 byte of all column's maximum length" PLUS "27 byte of tuple header followed by an optional null bitmap, an optional object ID field, and the user data")

Where do the 3 bytes come from?

Is there something wrong with my formula?


回答1:


Your calculation is off at several points.

  • Storage size of varchar, text (and character!) is, quoting the manual):

The storage requirement for a short string (up to 126 bytes) is 1 byte plus the actual string, which includes the space padding in the case of character. Longer strings have 4 bytes of overhead instead of 1. Long strings are compressed by the system automatically, so the physical requirement on disk might be less.

Bold emphasis mine to address question in comment.

  • The HeapTupleHeader occupies 23 bytes. But each tuple ("item" - row or index entry) has an item identifier at the start of the data page to it, totaling at the mentioned 27 bytes. The distinction is relevant as actual user data begins at a multiple of MAXALIGN from the start of each item, and the item identifier does not count against this offset - as well as the actual "tuple size".

  • 1 byte of padding due to data alignment (multiple of 8), which is used for the NULL bitmap in this case.

  • No padding for type varchar (but the additional byte mentioned above)

So, the actual calculation (with all columns filled to the maximum) is:

    23    -- heaptupleheader
 +   1    -- NULL bitmap (or padding if row has NO null values)
 +   9    -- columns ...
 + 101 
 +   2 
 + 101 
 +   4 
 +  11
-------------
   252 bytes

 +   4    -- item identifier at page start

Related:

  • Does not using NULL in PostgreSQL still use a NULL bitmap in the header?
  • Calculating and saving space in PostgreSQL

You'll find many more in the link list to the right of these answers.



来源:https://stackoverflow.com/questions/13524222/table-size-with-page-layout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!