Postgresql 表和索引的预期存储大小
我正在Oracle Linux Server 6.3版上使用postgresql 9.2.1 我正在努力获取表和索引的预期存储大小 多亏了这个网站的一些建议,我制作了如下表格的公式 --如果是表格Postgresql 表和索引的预期存储大小,postgresql,Postgresql,我正在Oracle Linux Server 6.3版上使用postgresql 9.2.1 我正在努力获取表和索引的预期存储大小 多亏了这个网站的一些建议,我制作了如下表格的公式 --如果是表格 postgres=# \d test Table "public.test" Column | Type | Modifiers ---------------+-----------------------+---------
postgres=# \d test
Table "public.test"
Column | Type | Modifiers
---------------+-----------------------+-----------
c1 | integer | not null
c2 | character varying(20) | not null
c3 | character varying(8) | not null
c4 | character varying(6) | not null
c5 | character varying(15) |
c6 | character varying(20) |
c7 | character varying(20) |
c8 | character varying(20) |
Indexes:
"idx_test" PRIMARY KEY, btree (c1, c3, c4, c5)
Tablespace: "test"
postgres=# insert into test values(1,
'11111111111111111111', -- 20(exactly same with max length of each column)
'11111111', -- 8
'111111', -- 6
'111111111111111', -- 15
'11111111111111111111', -- 20
'11111111111111111111', -- 20
'11111111111111111111');-- 20
INSERT 0 1
postgres=# select * from pgstattuple('test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
8192 | 1 | 81 | 0.99 | 0 | 0 | 0 | 8072 | 98.54
postgres=# insert into test values(2,
'11111111111111111111', -- 20(exactly same with max length of each column)
'11111111', -- 8
'111111', -- 6
'111111111111111', -- 15
'11111111111111111111', -- 20
'11111111111111111111', -- 20
'11111111111111111111');-- 20
INSERT 0 1
postgres=# select * from pgstattuple('test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
8192 | 2 | 162 | 1.98 | 0 | 0 | 0 | 7980 | 97.41
所以,我发现每个页面可以容纳88(X)个元组
- 实际存储中的元组大小:8072(第一次插入后的空闲空间)-7980(第二次插入后的空闲空间)=92
- 页面默认值=8192-8072(第一次插入后的可用空间)-92(元组大小)=28
- 9182-28=92*X(每页最大元组数)
postgres=# \d test_pkey
Index "public.idx_test"
Column | Type | Definition
---------------+-----------------------+---------------
c1 | integer | c1
c2 | character varying(20) | c2
c3 | character varying(8) | c3
c4 | character varying(6) | c4
primary key, btree, for table "public.test"
postgres=# truncate table test;
postgres=# vacuum;
postgres=# analyze;
postgres=# insert into test values(1,
'11111111111111111111', -- 20(exactly same with max length of each column)
'11111111', -- 8
'111111', -- 6
'111111111111111', -- 15
'11111111111111111111', -- 20
'11111111111111111111', -- 20
'11111111111111111111');-- 20
INSERT 0 1
postgres=# select * from pgstattuple('idx_test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
16384 | 1 | 56 | 0.34 | 0 | 0 | 0 | 8088 | 49.37
(1 row)
postgres=# select * from pgstatindex('idx_test');
version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
2 | 0 | 8192 | 1 | 0 | 1 | 0 | 0 | 0.79 | 0
(1 row)
postgres=# insert into test values(1,
'11111111111111111111', -- 20(exactly same with max length of each column)
'11111111', -- 8
'111111', -- 6
'111111111111111', -- 15
'11111111111111111111', -- 20
'11111111111111111111', -- 20
'11111111111111111111');-- 20
INSERT 0 1
postgres=# select * from pgstattuple('idx_test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
16384 | 2 | 112 | 0.68 | 0 | 0 | 0 | 8028 | 49
(1 row)
postgres=# select * from pgstatindex('idx_test');
version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
2 | 0 | 8192 | 1 | 0 | 1 | 0 | 0 | 1.52 | 0
(1 row)
同样,我发现每个页面可以容纳135(Y)个元组
- 实际存储中的元组大小:8088(第一次插入后的空闲空间)-8028(第二次插入后的空闲空间)=60
- 页面默认值=8192-8088(第一次插入后的可用空间)-60(元组大小)=44
- 8192-44=60*Y(每页最大元组数)
postgres=# select * from pgstattuple('test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
131072 | 1350 | 109350 | 83.43 | 0 | 0 | 0 | 6424 | 4.9
(1 row)
postgres=# select * from pgstattuple('idx_test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
90112 | 1350 | 54000 | 59.93 | 0 | 0 | 0 | 13580 | 15.07
(1 row)
postgres=# select * from pgstatindex('idx_test');
version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
2 | 1 | 81920 | 3 | 0 | 9 | 0 | 0 | 81.49 | 0
(1 row)
表的文件大小
1350(行数)/88(X)=15.34-->这意味着需要16页,这意味着文件大小为16*8192=131072。看起来不错
然而,指数sise是不同的
1350(行数)/135(Y)=10正好。。。文件大小需要10*8192,但需要90112
再插入一行,除此之外,索引大小应该扩展(如果我是对的),所以我尝试了,但没有更改
postgres=# insert into test values(27108,'sanjuk1052','20121022','233338','172,20,30,177','win7','IE','9,0');
INSERT 0 1
postgres=# select * from pgstattuple('test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
131072 | 1351 | 109431 | 83.49 | 0 | 0 | 0 | 6332 | 4.83
(1 row)
postgres=# select * from pgstattuple('idx_test');
table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
-----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
90112 | 1351 | 54040 | 59.97 | 0 | 0 | 0 | 13536 | 15.02
(1 row)
postgres=# select * from pgstatindex('idx_test');
version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
2 | 1 | 81920 | 3 | 0 | 9 | 0 | 0 | 81.55 | 0
(1 row)
我甚至不能确定这种方法是否合理,但这项工作必须完成,即使不是完美的
我需要我自己的公式,特别是为了获得预期的索引大小,包括由TOAST重新筛选的附加文件
如果您有任何建议,我们将不胜感激。您在这里遇到的真正问题之一是varchar没有使用恒定的空间量。随着时间的推移,这可能会使您的页面估计值偏离(您的估计值基本上是一个最大值,可能更小)。以你的桌子结构,我认为任何东西都不会被烤 这也会影响索引,因为您有可变长度的字段。因此,您可以预期您的估计值代表了一个最大的、未知的准确金额。实际大小将取决于实际数据,而不仅仅是模式和行数