简介
在postgresql数据库中,规划器会根据统计信息对我们执行语句选择最有执行路径。所以统计信息的有效,及时的更新对于我们优化数据库有较大帮助。在进程 autovacuum launcher中会数据库空闲时清理dead touple 的同时更新统计信息
ANALYZE语法
1 ANALYZE TABLENAME
使用语法:
ANALYZE [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
ANALYZE [ VERBOSE ] [ table_and_columns [, ...] ]
where option can be one of:
VERBOSE [ boolean ]
SKIP_LOCKED [ boolean ]
and table_and_columns is:
table_name [ ( column_name [, ...] ) ]
涉及参数
这里可以添加 VERBOSE,SKIP_LOCKED 两个参数
VERBOSE
输出分析的详细进程
SKIP_LOCKED
analyze 命令只需在表上加一个读锁,当执行到当前表时,当前表的读锁被堵塞时,将直接跳过,不会等待。
使用影响
analyze 命令只需在表上加一个读锁,因此它可以与表上的其他SQL命令并发执行。ANALYZE命令会收集表的每个字段的直方图和最常用数值的列表
对于大表,ANALYZE命令只读取表的部分内容做一个随机抽样,不读取表的所有内容,这样就保证了即使是在很大的表上也只需要很少时间就可以完成统计信息的收集。统计信息只是近似的结果,即使表内容实际上没有改变,运行ANALYZE命令后EXPLAIN命令显示的执行计划中的COST值也会有一些变化。为了增加所收集的统计信息的准确度,可以增大随机抽样比例,这可以通过调整参数“default_statistics_target”来实现,该参数可在session级别设置,比如在分析不同的表时设置不同的值。
示例
创建测试表并插入数据
create table text(id int);
insert into text(id) select generate_series(1,1234567);
调整参数default_statistics_target 并analyze查看执行时长对比。
当default_statistics_target值越大时,设置的抽样数据也就越长,analyze的执行时间也就越长.
2 EXPLAIN ANALYZE
使用语法
主要用于查看语句的实际运行时间
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement
使用影响
示例
postgres=# select count(1) from text where id is null ;
count
-------
0
(1 row)
Time: 41.889 ms
postgres=# begin; --开启事务
BEGIN
Time: 0.122 ms
postgres=*# explain analyze update text set id=null where id%41=0 ; --查看语句执行计划
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Update on text (cost=0.00..8718.85 rows=0 width=0) (actual time=65.310..65.311 rows=0 loops=1)
-> Seq Scan on text (cost=0.00..8718.85 rows=2232 width=10) (actual time=0.023..47.690 rows=10889 loops=1)
Filter: ((id % 41) = 0)
Rows Removed by Filter: 435501
Planning Time: 0.055 ms
Execution Time: 65.339 ms
(6 rows)
Time: 65.740 ms
postgres=*# select count(1) from text where id is null ; --语句已经变更表数据
count
-------
10889
(1 row)
Time: 36.887 ms
postgres=*# rollback --表数据回滚
;
ROLLBACK
Time: 0.153 ms
postgres=# end;
WARNING: there is no transaction in progress
COMMIT
Time: 0.372 ms
postgres=# select count(1) from text where id is null ; --表数据恢复为事务开启前状态
count
-------
0
(1 row)
Time: 117.977 ms
postgres=#