暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL 长事务中DML产生的数据无法被及时纳入统计信息导致的问题

digoal 2016-03-29
209

作者

digoal

日期

2016-03-29

标签

PostgreSQL , 统计信息 , 事务隔离级别 , 长事务


背景

PostgreSQL最低的事务隔离级别是read committed,因此在事务中产生的数据变化,在外部是不可见的,包括auto analyze也是不可见的。

例子:

```
postgres=# show autovacuum;
autovacuum


on
(1 row)

postgres=# show autovacuum_naptime ;
autovacuum_naptime


1s
(1 row)
```

会话A:

postgres=# create table t1(id int, info text); CREATE TABLE postgres=# begin; BEGIN postgres=# insert into t1 select generate_series(1,100000),'test'; INSERT 0 100000 postgres=# insert into t1 select generate_series(1,100000),'test'; INSERT 0 100000

会话B:

postgres=# analyze t1; ANALYZE postgres=# select * from pg_stats where attname ='id' and tablename='t1'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram ------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+---------------------- (0 rows)

会话A:

postgres=# select * from pg_stats where attname ='id' and tablename='t1'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram ------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+---------------------- (0 rows)

在会话A中手工执行完analyze后,生效:

```
postgres=# analyze t1;
ANALYZE
postgres=# select * from pg_stats where attname ='id' and tablename='t1';
schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct |
most_common_vals
|

                                                                                                                                                                                                      most_common_freqs


                                                                                                 |                                                                                                                                         
                                                                                                                                                       histogram_bounds                                                                    
                                                                                                                                                                                                                             | correlatio
复制

n | most_common_elems | most_common_elem_freqs | elem_count_histogram
------------+-----------+---------+-----------+-----------+-----------+------------+---------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------
--+-------------------+------------------------+----------------------
public | t1 | id | f | 0 | 4 | -0.492995 | {1,36,68,79,83,224,241,298,329,345,352,360,408,434,494,558,582,642,688,711,839,865,913,966,975,1078,1164,1297,1315,1323,1338,1357,1376,1515,1516,1545,15
47,1634,1672,1693,1800,1813,1929,1972,1985,2018,2051,2083,2094,2098,2106,2144,2152,2158,2163,2165,2170,2185,2188,2197,2220,2257,2312,2348,2422,2470,2580,2592,2594,2633,2655,2741,2782,2821,2950,2971,3097,3119,3138,3141,3181,3198,3252,3371
,3377,3391,3472,3491,3519,3538,3587,3648,3657,3687,3743,3820,3831,3870,3939,3943} | {6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e
-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.666
67e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.
66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05
,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e
-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05,6.66667e-05} | {6,1154,2342,3503,4516,5541,6567,7552,8482,9465,10474,11418,12381,13416,14407,15338,16328,17294,18265,19271,20219,21230,22222,23282,24
288,25285,26281,27333,28236,29136,30192,31132,32146,33085,34025,35011,36055,37109,38117,39137,40083,41082,42078,43029,44059,45056,46063,47140,48122,49216,50318,51339,52291,53286,54276,55311,56445,57435,58328,59193,60234,61110,62099,63128
,64152,65140,66126,67172,68166,69115,70155,71057,72166,73199,74246,75218,76172,77205,78274,79284,80261,81186,82187,83093,84065,85087,86065,87065,87993,89044,89990,91032,91986,93040,94077,95122,96070,96990,98051,99020,100000} | 0.50788
9 | | |
(1 row)
```

由于隔离级别的原因,会话B依旧不能读到pg_stats的版本

postgres=# select * from pg_stats where attname ='id' and tablename='t1'; schemaname | tablename | attname | inherited | null_frac | avg_width | n_distinct | most_common_vals | most_common_freqs | histogram_bounds | correlation | most_common_elems | most_common_elem_freqs | elem_count_histogram ------------+-----------+---------+-----------+-----------+-----------+------------+------------------+-------------------+------------------+-------------+-------------------+------------------------+---------------------- (0 rows)

那么这就会导致一个问题。

如果会话中执行了大量的DML,数据发送了较大的变化。或者会话中有新建的临时表,或者普通表,执行计划可能有问题。

这个问题在复杂查询中尤为突出。

例如有比较多的JOIN的查询,虽然数据量可能非常庞大,但是可能由于没有统计信息就走nest loop了。

优化建议:

在事务中的每条DML语句后面,加一条analyze 响应的表的操作。

PostgreSQL 许愿链接

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

9.9元购买3个月阿里云RDS PostgreSQL实例

PostgreSQL 解决方案集合

德哥 / digoal's github - 公益是一辈子的事.

digoal's wechat

文章转载自digoal,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论