pg统计信息
一、测试用例
create table student(sno int, sname varchar(100),ssex int);
create index idx_sno on student(sno);
insert into student values(1,'zs',1);
insert into student values(2 , 'ls',1);
insert into student values(3 , 'ww',1);
insert into student values(4, 'zl',1);
insert into student values(5,'zs',2);
insert into student values(6, 'ls',2);
insert into student values(7,null,null);
select relname,relpages,reltuples from pg_class where relname='student';
select * from pg_statistic where starelid=24676;
select staattnum,stanullfrac,stawidth,stadistinct from pg_statistic where starelid=24676;
select staattnum,stakind1,stakind2,stakind3,stakind4,stakind5 from pg_statistic where starelid=24676;
select staattnum,stakind1,staop1,stanumbers1,stavalues1 from pg_statistic where starelid=24676;
二、
1、单列统计信息类型说明
STATISTIC_KIND_MCV:高频值(常见值),在一个列里出现最频繁的值,按照出现的频率进行排序,并且生成 一个一一对应的频率数组,这样就能知道一个列中有哪些高频值,这些高颇值的频率是多少。
STATISTIC_KIND_HISTOGRAM:直方图, PostgreSQL数据库使用等频直方图来描述一个列中的数据的分布,高频值不会出现在直方图中,这就保证了数据的分布是相对平坦的。
STATISTIC_KIND_CORRELATION:相关系数,相关系数记录的是当前列未排序的数据分布和排序后的数据分布的相关性,这个值通常在索引扫描时用来估计代价,假设一个列未排序和排序之后的相关性是0,也就是完全不相关,那么索引扫描的代价就会高一些。
STATISTIC_KIND_MCELEM:类型高频值(常见值),用于数组类型或者一些其他类型,PostgreSQL数据库提供了ts_typanalyze系统函数来负责生成这种类型的统计信息。
STATISTIC_KIND_DECHIST:数组类型直方图,用于给数组类型生成直方图, PostgreSQL数据库提供了array_typanalyze系统函数来负责生成这种类型的统计信息。
STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM: 为Range类型生成一个基于长度的直方图统计信息,用户可以自定义Range 类型,例如CREATE TYPE floatrange AS RANGE
(subtype=float8, subtype_diff=float8mi),PostgreSQL数据库提供了range_typanalyze系统函数负责生成这种类型的统计信息。
STATISTIC_KIND_BOUNDS_HISTO_GRAM:为Range类型生成一个基于边界的直方图,这种类型的直方图也通过range_typanalyze系统函数来进行统计。
2、多列统计信息类型说明
STATS_EXT_NDISTINCT:和单列统计信息中的stadistinct是类似的,stadistinct中记录的是单列中去掉NULL值和消重之后的数据量或者比例,STATS_EXT_NDISTINCT类型的统计信息则记录的是基于多列的消重之后的数据量。
STATS_EXT_DEPENDENCIES:计算各个列之间的函数依赖度,通过函数依赖度计算各个列之间的依赖关系,从而得到准确的统计信息。
1、PG_CLASS 系统表
relpages字段:记录了当前表占用了多少个页面;
reltuples字段:记录了当前表共有多少条元组;
2、PG STATISTIC 系统表:保存单列 的统计信息
starelid/staattnum:对应的表的 OID (来自 PG_CLASS)和列编号(来自PG_ATTRIBUTES);
stanullfrac: NULL值率, 表示一个熟悉(列)里 NULL值所占的比例;
stawidth:计算该属性(列)的平均宽度;
int类型:4
varchar类型:1(varchar类型的header占用1个字节长度)+ 值平均宽度
stadistinct:计算该属性消重之后的数据的个数或比例,有3中取值情况:
=0,代表未知或者未计算的情况;
>0,代表消除重复值之后的个数,不常使用这种情况;
<0,其绝对值是去重之后的个数占总个数的比例,通常使用这种类型;
stakind:统计信息的形式
#define STATISTIC_KIND_MCV 1
#define STATISTIC_KIND_HISTOGRAM 2
#define STATISTIC_KIND_CORRELATION 3
#define STATISTIC_KIND_MCELEM 4
#define STATISTIC_KIND_DECHIST 5
槽位:
PostgreSQL 数据库对每一个属性(列)的统计目前最多只能应用 STATISTIC_NUM_SLOTS=5种方法,因此在 PG_STATISTIC 会有 stakind(1-5)、staop(1-5)、stanumbers[1](1-5)、stavalues(1-5),分别是5个槽位。如果 stakind 不为0,那么表明这个槽位有统计信息 ,第一个统计方法统计的信息首先会记录到第一个槽位(stakind1、staop1、stanumbers1[1]、stavalues1),第二个统计方法的统计信息会记录到第二个槽位(stakind2、staop2、stanumbers2[1]、stavalues2),依此类推。
staop:统计过程中涉及的操作符。
stanumbers:存放统计信息的高频值数组或者存放相关系数。例如 stakind1保存的统计信息类型是 STATISTIC_KIND_MCV,那么在 stanumbers1中保存的就是高频值数组,数组中记录的是每个高频值所占的频率值,再例如 stakind3中保存的统计信息类型是STATISTIC_KIND_CORRELATION ,那么在 stanumbers3 中保存的就是相关系数。
stavalues:统计值的数组,如果stakind1保存的统计信息类型是STATISTIC_KIND_MCV,那么在 stavalues 中保存的就是高频值对应的值,它和 stanumbers 中的高颇值数组的频率值一一对应。如果stakind1保存的统计信息类型是 STATISTIC_KIND_HISTOGRAM ,那么在stanumbers1 中保存的是直方图中的桶的信息 ,由于直方图是等频直方图,因此只要记录了每个桶的边界值,就可以获得每个桶的平均比例。
3、PG_STATISTIC_EXT系统表:保存的是多列的统计信息,用户需要显式地使用CREATE STATISTICS语句对一个表创建多列统计信息。
通过CREATE STATISTICS语句创建统计信息之后只是在PG_STATISTIC_EXT系统表中增加了一个统计信息项,这时候并没有真正对指定表上的属性去做统计分析,只有在用户对表再次ANALYZE的时候,而且ANALYZE的表的属性满足了多列统计信息的要求,才会生成多列统计信息。
属性 类型 说明
stxreli Oid 统计信息属于哪个表
stxname NameData 统计信息的名字
stxnamespace Oid 统计信息的namespace
stxowner Oid 统计信息的创建者
stxkeys int2vector 统计哪些列
stxkind char 多列统计的类型,目前支持两种类型:
#define STATS EXT NDISTINCT ’d'
#define STATS EXT DEPENDENCIES ’r
stxndistinct pg_ndistinct STATS EXT NDISTINCT类型的统计信息
stxdependencies pg_dependencies ST ATS EXT DEPENDENCIES类型的统计信息
- 点赞
- 收藏
- 关注作者
评论(0)