Postgres10高性能开发(3)统计

本文深入探讨了如何通过统计分析,如VACUUM、ANALYZE及DDL操作,优化PostgreSQL数据库的查询性能。详细讲解了单列统计、扩展统计及函数依赖的概念,以及如何利用这些统计信息来提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

统计

解释计划通过统计分析各种方式的成本来选择"最优"的执行路径

VACUUM, ANALYZE或一些DDL操作(如CREATE INDEX)可以重新生成统计

单列统计

pg_class

记录表、索引中的行数

VACUUM, ANALYZE或一些DDL操作(如CREATE INDEX)生成统计

SELECT relname,relkind,reltuples,relpages from pg_class where relname like 'bms_t_group_hotel%'

#Result
relname                 relkind  reltuples   relpages
bms_t_group_hotel	    r	     28	         2
bms_t_group_hotel_pkey	i	     28	         2
  • relname:统计对象,包括表、视图、索引等
  • relkind:
    • i表示索引
    • r表示表
    • S表示序列
    • t标识TOAST表
    • v标识视图
    • m标识物化视图
    • c标识组合类型
    • f表示外部表
    • p表示分区表
  • reltuples:表中行数
  • relpages:磁盘中占用的页数
pg_statistic

记录表内容的统计信息

ANALYZE生成统计

pg_statistic的数据可通过pg_stats视图查看

https://www.postgresql.org/docs/10/view-pg-stats.html

SELECT attname, inherited, n_distinct,
       array_to_string(most_common_vals, E'\n') as most_common_vals
FROM pg_stats
WHERE tablename = 'road';

#RESULT
 attname | inherited | n_distinct |          most_common_vals
---------+-----------+------------+------------------------------------
 name    | f         |  -0.363388 | I- 580                        Ramp+
         |           |            | I- 880                        Ramp+
         |           |            | Sp Railroad                       +
         |           |            | I- 580                            +
         |           |            | I- 680                        Ramp
 name    | t         |  -0.284859 | I- 880                        Ramp+
         |           |            | I- 580                        Ramp+
         |           |            | I- 680                        Ramp+
         |           |            | I- 580                            +
         |           |            | State Hwy 13                  Ramp
  • tablename:表名
  • attname: 列名
  • null_frac: 列中null值比例
  • avg_width:列平均宽度(单位byte)
  • n_distinct:
    • 如果值大于0,则为列中distinct值的数量;
    • 如果值小于0,则其绝对值为distinct值数量/总行数
  • most_common_vals:列中最常见的值列表。(如果没有值比任何其他值更常见,则为空。)
  • most_common_freqs:最常见值的频率列表,即每个值的出现次数除以总行数
  • histogram_bounds:一个值列表,用于将列的值划分为大致相等的总体组
  • correlation: 物理行排序与列值的逻辑排序之间的统计相关性,范围从-1到+1,值越接近-1或+1则相关性越低
  • most_common_elems:为数组类型列时, 最常出现在列值内的非null元素值列表
  • most_common_elems_freqs:为数组类型列时, 最常出现在列值内的非null元素值的频率
  • elem_count_histogram:为数组类型列时, 列值中不同非空元素值计数的直方图,后跟不同非空元素的平均数

扩展统计

如果查询针对多个字段,单列统计只针对了单个列,无法评估多列值组合下的数据区分度。扩展统计可以解决此问题。

由于列的组合数量非常大,扩展统计需要手动创建

函数依赖

当字段A和字段B存在強依赖关系,例如邮编和城市之间有依赖关系,可以使用功能依赖

CREATE STATISTICS stts(dependencies) ON zip, city FROM zipcodes;

zip能完全确定city,city对应多个zip,因此zip要放在前面

函数依赖当前仅在将列与常量值进行比较的简单相等条件时应用

SELECT * FROM zipcodes WHERE city ='合肥'AND zip = '230001';

此时解释计划评估时将只使用zip评估区分度,忽略city

多变量N-Distinct计数

为指定的多个列收集统计信息

CREATE STATISTICS stts2 (ndistinct) ON zip, state, city FROM zipcodes;

ANALYZE zipcodes;

SELECT stxkeys AS k, stxndistinct AS nd
  FROM pg_statistic_ext
  WHERE stxname = 'stts2';
-[ RECORD 1 ]--------------------------------------------------------
k  | 1 2 5
nd | {"1, 2": 33178, "1, 5": 33178, "2, 5": 27435, "1, 2, 5": 33178}
(1 row)

统计结果预计

  • zip和state有33178组DISTINCT值
  • zip和city有33178组DISTINCT值
  • state和city有27435组DISTINCT值
  • zip、state和state有33178组DISTINCT值

建议只在分组列组合上创建统计对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值