规划器使用的统计信息(pg_class更改)

今天测试pg_class系统表里的那个reltuples字段,可是插入数据以后他老是不自动更新,差异下文档如下描述。
为了性能不能每时每刻更新,手动可以使用“ VACUUM,ANALYZE,和几个 DDL 命令,比如 CREATE INDEX 更新”
======================================================
[quote]
[url]http://www.pgsqldb.org/pgsqldoc-cvs/planner-stats.html[/url]
统计的一个部分就是每个表和索引中的记录总数,以及每个表和索引占据的磁盘块数。 这个信息保存在 pg_class 的 reltuples 和 relpages 字段中。我们可以用类似下面的查询检索这些信息:

SELECT relname, relkind, reltuples, relpages FROM pg_class WHERE relname LIKE 'tenk1%';

relname | relkind | reltuples | relpages
----------------------+---------+-----------+----------
tenk1 | r | 10000 | 358
tenk1_hundred | i | 10000 | 30
tenk1_thous_tenthous | i | 10000 | 30
tenk1_unique1 | i | 10000 | 30
tenk1_unique2 | i | 10000 | 30
(5 rows)
我们在这里可以看到 tenk1 有 10000 行, 它的索引也有这么多行,但是索引远比表小得多(很正常)。

出于效率考虑,reltuples 和 relpages 不是实时更新的, 因此它们通常包含可能有些过时的数值。 它们被 VACUUM,ANALYZE,和几个 DDL 命令,比如 CREATE INDEX 更新。一个独立的 ANALYZE, 也就是没有和 VACUUM 在一起的, 生成一个reltuples 的近似数值, 因为它并没有读取表里的每一行。规划器将把 pg_class 表里面的数值调整为和当前的物理表尺寸匹配,以此获取一个更接近的近似值。

大多数查询只是检索表中行的一部分,因为它们有限制待查行的 WHERE 子句。 因此规划器需要对WHERE子句的选择性(selectivity)进行评估, 选择性也就是符合WHERE子句中每个条件的部分。 用于这个目的的信息存储在 pg_statistic 系统表中。 在 pg_statistic 中的记录是由 ANALYZE 和 VACUUM ANALYZE 命令更新的, 并且总是近似值,即使刚刚更新完也不例外。

除了直接查看 pg_statistic 之外, 我们手工检查统计的时候最好查看它的视图 pg_stats。 pg_stats 设计成更具可读性。 而且,pg_stats 是所有人都可以读取的, 而 pg_statistic 只能由超级用户读取。 (这样就可以避免非特权用户从统计信息中获取一些和其他人的表内容相关的信息。 pg_stats 视图是受约束的,只显示当前用户可读的表。) 比如,我们可以∶

SELECT attname, n_distinct, most_common_vals FROM pg_stats WHERE tablename = 'road';

attname | n_distinct | most_common_vals

---------+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
name | -0.467008 | {"I- 580 Ramp","I- 880 Ramp","Sp Railroad ","I- 580 ","I- 680 Ramp","I- 80 Ramp","14th St ","5th St ","Mission Blvd","I- 880 "}
thepath | 20 | {"[(-122.089,37.71),(-122.0886,37.711)]"}
(2 rows)

pg_stats 在 Section 42.43 里详细描述。

在 pg_statistic 李存储的信息的数量,特别是 给每个字段用的 most_common_vals 和 histogram_bounds 数组上的最大记录数目可以用 ALTER TABLE SET STATISTICS 命令设置, 或者是用运行时参数 default_statistics_target 进行全局设置。 目前缺省的限制是 10 个记录。 提升该限制应该可以做出更准确的规划器估计,特别是对那些有不规则数据分布的字段而言, 付出的代价是在 pg_statistic 里使用了更多空间,并且需要略微多一些的时间计算估计数值。 相比之下,比较低的限制可能更适合那些数据分布比较简单的字段。
[/quote]
[quote]22.1.2. 更新规划器统计

PostgreSQL 的查询规划器依赖一些有关表内容的统计信息用以为查询生成好的规划。 这些统计是通过ANALYZE 命令获得的,你可以直接调用这条命令, 也可以把它当做 VACUUM 里的一个可选步骤来调用。 拥有合理准确的统计是非常重要的,否则,选择了恶劣的规划很可能降低数据库的性能。

和为了回收空间做清理一样,经常更新统计信息也是对更新频繁的表更有用。 不过,即使是更新非常频繁的表,如果它的数据的统计分布并不经常改变,那么也不需要更新统计信息。 一条简单的拇指定律就是想想表中字段的最大很最小值改变的幅度。 比如,一个包含行更新时间的 timestamp 字段将是随着行的追加和更新稳定增长最大值的; 这样的字段可能需要比那些包含访问网站的 URL 的字段更频繁一些更新统计信息。 那些 URL 字段可能改变得一样频繁,但是其数值的统计分布的改变相对要缓慢得多。

我们可以在特定的表,甚至是表中特定的字段上运行 ANALYZE, 所以如果你的应用有需求的话,我们是可以对某些信息更新得比其它信息更频繁的。 不过,在实际中,这种做法的有用性是值得怀疑的。 从 PostgreSQL 7.2 开始, ANALYZE 是一项相当快的操作,即时在大表上也很快, 因为它使用了统计学上的随机采样的方法进行行采样, 而不是把每一行都读取进来。因此,每隔一段时间对整个数据库运行一便这条命令可能更简单。

提示: 尽管用 ANALYZE 按字段进行挖掘的方式可能不是很实用, 但你可能还是会发现值得按字段对 ANALYZE 收集的统计信息的详细级别进行调整。 那些经常在WHERE子句里使用的字段如果有非常不规则的数据分布, 那么就可能需要比其它字段更细致的数据图表.参阅 ALTER TABLE SET STATISTICS.

我们对大多数节点都建议在每天的低使用时段安排一次数据库范围的 ANALYZE: 这个任务可以有效地和每天的 VACUUM 组合在一起。 不过,这对那些表统计信息改变相对缓慢的节点可能会过于夸张, 而且少一些的 ANALYZE 也足够了。
[url]http://www.kuqin.com/postgreSQL8.1_doc/maintenance.html[/url][/quote]

你可能感兴趣的:(PostgreSQL)