PostgreSQL 9.5 新特性 高斯(正态)分布和指数分布 数据生成器

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

PostgreSQL 9.5 对pgbench的功能增强。

  • Allow counting of pgbench transactions that take over a specified amount of time (Fabien Coelho)

    This is controlled by new --latency-limit option.

  • Allow pgbench to generate Gaussian/exponential distributions using \setrandom (Kondo Mitsumasa, Fabien Coelho)

  • Allow pgbench's \set command to handle multi-operator expressions (Robert Haas, Fabien Coelho)

1. 允许在\set中使用更复杂的表达式(正负,加 减 乘 除 余,括号)。

 
 

\set varname expression
Sets variable varname to an integer value calculated from expression. The expression may contain integer constants such as 5432, references to variables :variablename, and expressions composed of unary (-) or binary operators (+, -, *, /, %) with their usual associativity, and parentheses.

Examples:
\set ntellers 10 * :scale
\set aid (1021 * :ntellers) % (100000 * :scale) + 1


2. 允许设置--latency-limit,执行时间超过限制的SQL将分开统计和显示为late,与--rate同时使用时,超出限制并且未发送到数据库执行的SQL记为skipped。

 
 

-L limit
--latency-limit=limit
Transaction which last more than limit milliseconds are counted and reported separately, as late.

When throttling is used (--rate=...), transactions that lag behind schedule by more than limit ms, and thus have no hope of meeting the latency limit, are not sent to the server at all. They are counted and reported separately as skipped.

-R rate
--rate=rate
Execute transactions targeting the specified rate instead of running as fast as possible (the default). The rate is given in transactions per second. If the targeted rate is above the maximum possible rate, the rate limit won't impact the results.

The rate is targeted by starting transactions along a Poisson-distributed schedule time line. The expected start time schedule moves forward based on when the client first started, not when the previous transaction ended. That approach means that when transactions go past their original scheduled end time, it is possible for later ones to catch up again.

When throttling is active, the transaction latency reported at the end of the run is calculated from the scheduled start times, so it includes the time each transaction had to wait for the previous transaction to finish. The wait time is called the schedule lag time, and its average and maximum are also reported separately. The transaction latency with respect to the actual transaction start time, i.e. the time spent executing the transaction in the database, can be computed by subtracting the schedule lag time from the reported latency.

If --latency-limit is used together with --rate, a transaction can lag behind so much that it is already over the latency limit when the previous transaction ends, because the latency is calculated from the scheduled start time. Such transactions are not sent to the server, but are skipped altogether and counted separately.

A high schedule lag time is an indication that the system cannot process transactions at the specified rate, with the chosen number of clients and threads. When the average transaction execution time is longer than the scheduled interval between each transaction, each successive transaction will fall further behind, and the schedule lag time will keep increasing the longer the test run is. When that happens, you will have to reduce the specified transaction rate.


3. 可以生成正态分布或指数分布的测试数据。

(原来只能生成概率一致的随机分布值)
 
 

\setrandom varname min max [ uniform | { gaussian | exponential } threshold ]
Sets variable varname to a random integer value between the limits min and max inclusive. Each limit can be either an integer constant or a :variablename reference to a variable having an integer value.

高斯分布(正态分布)的概率峰值出现在min,max的数学期望值即(max + min) / 2.0
67%的值分布在以min,max数学期望为中心的 1.0 / threshold 这个区间。
95%的值分布在min,max数学期望为中心的 2.0 / threshold 这个区间。
所以threshold越大,数据数据越集中在min,max的数学期望附近。

By default, or when uniform is specified, all values in the range are drawn with equal probability. Specifying gaussian or exponential options modifies this behavior; each requires a mandatory threshold which determines the precise shape of the distribution.

For a Gaussian distribution, the interval is mapped onto a standard normal distribution (the classical bell-shaped Gaussian curve) truncated at -threshold on the left and +threshold on the right. 
To be precise, if PHI(x) is the cumulative distribution function of the standard normal distribution, 
with mean mu defined as (max + min) / 2.0, 
then value i between min and max inclusive is drawn with probability: 
min,max区间取i值的概率如下,(其中PHI(x)是正态分布的积分函数):
(PHI(2.0 * threshold * (i - min - mu + 0.5) / (max - min + 1)) - PHI(2.0 * threshold * (i - min - mu - 0.5) / (max - min + 1))) / (2.0 * PHI(threshold) - 1.0). 
Intuitively, the larger the threshold, the more frequently values close to the middle of the interval are drawn, and the less frequently values close to the min and max bounds. 
About 67% of values are drawn from the middle 1.0 / threshold and 95% in the middle 2.0 / threshold; 
67%的值分布在以min,max数学期望为中心的 1.0 / threshold 这个区间。
95%的值分布在min,max数学期望为中心的 2.0 / threshold 这个区间。
for instance, if threshold is 4.0, 67% of values are drawn from the middle quarter and 95% from the middle half of the interval. 
The minimum threshold is 2.0 for performance of the Box-Muller transform. (性能考虑,2.0为最小threshold值)。

指数分布:
For an exponential distribution, the threshold parameter controls the distribution by truncating a quickly-decreasing exponential distribution at threshold, and then projecting onto integers between the bounds. 
To be precise, value i between min and max inclusive is drawn with probability: 
min,max区间取i值的概率如下:
(exp(-threshold*(i-min)/(max+1-min)) - exp(-threshold*(i+1-min)/(max+1-min))) / (1.0 - exp(-threshold)). 

Intuitively, the larger the threshold, the more frequently values close to min are accessed, and the less frequently values close to max are accessed. (threshold越大,随机值接近min的概率越大,反之,threshold越小,随机值接近max的概率越大)
The closer to 0 the threshold, the flatter (more uniform) the access distribution. 
注意上面这句话,threshold 越接近0,则越趋于随机分布,而不是指数分布。看后面的图。
A crude approximation of the distribution is that the most frequent 1% values in the range, close to min, are drawn threshold% of the time. 
The threshold value must be strictly positive.

Example:
\setrandom aid 1 :naccounts gaussian 5.0


例子:

生成高斯分布的一组数据。

约67%的值分布在以min,max数学期望为中心的 1.0 / 100 这个区间。
约95%的值分布在以min,max数学期望为中心的 2.0 / 100 这个区间。
 
 

postgres=# create table test(id int);
CREATE TABLE
postgres=# \q

pg95@db-172-16-3-150-> vi test.sql
\setrandom id 1 50000 gaussian 100.0
insert into test values (:id);


--latency-limit=0.2 表示响应时间超过0.2毫秒的请求另外显示。
 
  

pg95@db-172-16-3-150-> pgbench -M prepared -n -r -f ./test.sql -P 2 -c 16 -j 16 -T 10 --latency-limit=0.2
progress: 2.0 s, 93423.3 tps, lat 0.164 ms stddev 0.122
progress: 4.0 s, 95957.7 tps, lat 0.164 ms stddev 0.109
progress: 6.0 s, 95074.0 tps, lat 0.166 ms stddev 0.116
progress: 8.0 s, 95760.4 tps, lat 0.165 ms stddev 0.111
progress: 10.0 s, 95711.8 tps, lat 0.165 ms stddev 0.108
transaction type: Custom query
scaling factor: 1
query mode: prepared
number of clients: 16
number of threads: 16
duration: 10 s
number of transactions actually processed: 951872

这里显示了请求响应时间超过0.2毫秒的占比。
 
  

number of transactions above the 0.2 ms latency limit: 175929 (18.482 %)
latency average: 0.165 ms
latency stddev: 0.113 ms
tps = 95165.492751 (including connections establishing)
tps = 95694.059134 (excluding connections establishing)
statement latencies in milliseconds:
        -0.002321       \setrandom id 1 50000 gaussian 100.0
        0.160266        insert into test values (:id);


使用R来绘制一下正态分布:
 
 

> install.packages("RPostgreSQL")
> library(RPostgreSQL)

载入需要的程辑包:DBI
警告信息:
1: 程辑包‘RPostgreSQL’是用R版本3.1.3 来建造的 
2: 程辑包‘DBI’是用R版本3.1.3 来建造的 
 
  

> drv <- dbDriver("PostgreSQL")
> con <- dbConnect(drv, host='172.16.3.150', port='1922', dbname='postgres', user='postgres')
> rs <- dbGetQuery(con, 'with t (cnt) as (select count(*) as cnt from test) select id,count(*)/(t.cnt::numeric) from test, t group by id,t.cnt')
> plot(rs)

ba22f610c52d94bce4ac6187891b787fed5b148f
约67%的值分布在以min,max数学期望为中心的 1.0 / 100 这个区间(24750 至 25250)。
约95%的值分布在以min,max数学期望为中心的 2.0 / 100 这个区间(24500 至 25500)。

修改一下threshold, 改为5,将有95%的数据分布在2/5的区间内(15000 至 35000)。
 
  

postgres=# truncate test;
TRUNCATE TABLE
pg95@db-172-16-3-150-> vi test.sql
\setrandom id 1 50000 gaussian 5.0
insert into test values (:id);

pg95@db-172-16-3-150-> pgbench -M prepared -n -r -f ./test.sql -P 2 -c 16 -j 16 -T 10 --latency-limit=0.2
progress: 2.0 s, 93514.9 tps, lat 0.163 ms stddev 0.119
progress: 4.0 s, 94764.7 tps, lat 0.167 ms stddev 0.117
progress: 6.0 s, 95041.7 tps, lat 0.166 ms stddev 0.112
progress: 8.0 s, 95312.3 tps, lat 0.166 ms stddev 0.112
progress: 10.0 s, 95035.6 tps, lat 0.166 ms stddev 0.112
transaction type: Custom query
scaling factor: 1
query mode: prepared
number of clients: 16
number of threads: 16
duration: 10 s
number of transactions actually processed: 947354
number of transactions above the 0.2 ms latency limit: 176537 (18.635 %)
latency average: 0.166 ms
latency stddev: 0.114 ms
tps = 94726.249444 (including connections establishing)
tps = 95332.979889 (excluding connections establishing)
statement latencies in milliseconds:
        -0.002318       \setrandom id 1 50000 gaussian 5.0
        0.160983        insert into test values (:id);

重新绘制曲线:
4fc3700dc6f84df3afb46426e7871543d6fe580f

指数分布例子:

threshold越大,越多的值分布在min附近。
threshold越小,当趋近于0时,接近随机分布,而不是曲线反转。
threshold不能小于0。
 
 
postgres=# truncate test;
TRUNCATE TABLE

pg95@db-172-16-3-150-> vi test.sql
\setrandom id 1 50000 exponential 50000
insert into test values (:id);

pg95@db-172-16-3-150-> pgbench -M prepared -n -r -f ./test.sql -P 2 -c 16 -j 16 -T 10
progress: 2.0 s, 94095.8 tps, lat 0.162 ms stddev 0.112
progress: 4.0 s, 95611.9 tps, lat 0.165 ms stddev 0.108
progress: 6.0 s, 94929.7 tps, lat 0.166 ms stddev 0.121
progress: 8.0 s, 96159.4 tps, lat 0.164 ms stddev 0.102
progress: 10.0 s, 95586.2 tps, lat 0.165 ms stddev 0.109
transaction type: Custom query
scaling factor: 1
query mode: prepared
number of clients: 16
number of threads: 16
duration: 10 s
number of transactions actually processed: 952791
latency average: 0.164 ms
latency stddev: 0.111 ms
tps = 95271.583072 (including connections establishing)
tps = 95879.681335 (excluding connections establishing)
statement latencies in milliseconds:
        -0.002375       \setrandom id 1 50000 exponential 1.0
        0.160051        insert into test values (:id);

postgres=# analyze test;
ANALYZE
从most_common_vals和most_common_freqs可以观察到,threshold越大,越多的值分布在min附近 。
postgres=# select * from pg_stats where attname='id' and tablename='test';
-[ RECORD 1 ]----------+-----------------------------------------------
schemaname             | public
tablename              | test
attname                | id
inherited              | f
null_frac              | 0
avg_width              | 4
n_distinct             | 11
most_common_vals       | {1,2,3,4,5}
most_common_freqs      | {0.632533,0.231967,0.0867,0.0306333,0.0112333}
histogram_bounds       | {6,6,6,6,7,12}
correlation            | 0.458732
most_common_elems      | 
most_common_elem_freqs | 
elem_count_histogram   | 

如图:
af0ae37758b78ea9474cec561d1d5b3c378655c2
再提供几张图,threshold分别是1,10,100,1000,10000:
注意纵坐标的概率值。
9067fc0c38edff039c9263438e13987920889049

bde62dd7d67d20bd29030d0ab52dffdbbe8476e9

0891ace0da9033e54356363a1ef1eb0e57038db2

3bcc8a8d6d7e6361c5ff0ce177c37bd89bd38ca4

6c7c2e27b63c9458745c3563a6977733374449a6
threshold=0.000001:已经接近随机分布了。
92cd2bd79767da96f93bccdbc4f44b0ed30e5e07
可以看出,当threshold越来越小时,开始接近随机分布。

[参考]
2. src/bin/pgbench/pgbench.c
 
 

产生一个随机值
/* random number generator: uniform distribution from min to max inclusive */
static int64
getrand(TState *thread, int64 min, int64 max)
{
        /*
         * Odd coding is so that min and max have approximately the same chance of
         * being selected as do numbers between them.
         *
         * pg_erand48() is thread-safe and concurrent, which is why we use it
         * rather than random(), which in glibc is non-reentrant, and therefore
         * protected by a mutex, and therefore a bottleneck on machines with many
         * CPUs.
         */
        return min + (int64) ((max - min + 1) * pg_erand48(thread->random_state));
}
产生一个指数分布的随机值
/*
 * random number generator: exponential distribution from min to max inclusive.
 * the threshold is so that the density of probability for the last cut-off max
 * value is exp(-threshold).
 */
static int64
getExponentialRand(TState *thread, int64 min, int64 max, double threshold)
{
        double          cut,
                                uniform,
                                rand;

        Assert(threshold > 0.0);
        cut = exp(-threshold);
        /* erand in [0, 1), uniform in (0, 1] */
        uniform = 1.0 - pg_erand48(thread->random_state);

        /*
         * inner expresion in (cut, 1] (if threshold > 0), rand in [0, 1)
         */
        Assert((1.0 - cut) != 0.0);
        rand = -log(cut + (1.0 - cut) * uniform) / threshold;
        /* return int64 random number within between min and max */
        return min + (int64) ((max - min + 1) * rand);
}
产生一个高斯分布(正态分布)的随机值
/* random number generator: gaussian distribution from min to max inclusive */
static int64
getGaussianRand(TState *thread, int64 min, int64 max, double threshold)
{
        double          stdev;
        double          rand;

        /*
         * Get user specified random number from this loop, with -threshold <
         * stdev <= threshold
         *
         * This loop is executed until the number is in the expected range.
         *
         * As the minimum threshold is 2.0, the probability of looping is low:
         * sqrt(-2 ln(r)) <= 2 => r >= e^{-2} ~ 0.135, then when taking the
         * average sinus multiplier as 2/pi, we have a 8.6% looping probability in
         * the worst case. For a 5.0 threshold value, the looping probability is
         * about e^{-5} * 2 / pi ~ 0.43%.
         */
        do
        {
                /*
                 * pg_erand48 generates [0,1), but for the basic version of the
                 * Box-Muller transform the two uniformly distributed random numbers
                 * are expected in (0, 1] (see
                 * http://en.wikipedia.org/wiki/Box_muller)
                 */
                double          rand1 = 1.0 - pg_erand48(thread->random_state);
                double          rand2 = 1.0 - pg_erand48(thread->random_state);

                /* Box-Muller basic form transform */
                double          var_sqrt = sqrt(-2.0 * log(rand1));

                stdev = var_sqrt * sin(2.0 * M_PI * rand2);

                /*
                 * we may try with cos, but there may be a bias induced if the
                 * previous value fails the test. To be on the safe side, let us try
                 * over.
                 */
        }
        while (stdev < -threshold || stdev >= threshold);

        /* stdev is in [-threshold, threshold), normalization to [0,1) */
        rand = (stdev + threshold) / (threshold * 2.0);

        /* return int64 random number within between min and max */
        return min + (int64) ((max - min + 1) * rand);
}
产生泊松分布随机值
/*
 * random number generator: generate a value, such that the series of values
 * will approximate a Poisson distribution centered on the given value.
 */
static int64
getPoissonRand(TState *thread, int64 center)
{
        /*
         * Use inverse transform sampling to generate a value > 0, such that the
         * expected (i.e. average) value is the given argument.
         */
        double          uniform;

        /* erand in [0, 1), uniform in (0, 1] */
        uniform = 1.0 - pg_erand48(thread->random_state);

        return (int64) (-log(uniform) * ((double) center) + 0.5);
}
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
29天前
|
存储 关系型数据库 分布式数据库
PolarDB常见问题之PolarDB冷存数据到OSS之后恢复失败如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
1月前
|
SQL 关系型数据库 分布式数据库
在PolarDB中,行数评估是通过对表的统计数据、基数估计以及算子代价模型来进行估算的。
【2月更文挑战第14天】在PolarDB中,行数评估是通过对表的统计数据、基数估计以及算子代价模型来进行估算的。
82 1
|
6月前
|
关系型数据库 MySQL Linux
TiDB实时同步数据到PostgreSQL(三) ---- 使用pgloader迁移数据
使用PostgreSQL数据迁移神器pgloader从TiDB迁移数据到PostgreSQL,同时说明如何在最新的Rocky Linux 9(CentOS 9 stream也适用)上通过源码编译安装pgloader。
225 0
|
2天前
|
SQL 关系型数据库 MySQL
关系型数据库插入数据的语句
使用SQL的`INSERT INTO`语句向关系型数据库的`students`表插入数据。例如,插入一个`id`为1,`name`为&#39;张三&#39;,`age`为20的记录:`INSERT INTO students (id, name, age) VALUES (1, &#39;张三&#39;, 20)。如果`id`自增,则可简化为`INSERT INTO students (name, age) VALUES (&#39;张三&#39;, 20)`。
5 2
|
2天前
|
SQL 存储 Oracle
关系型数据库查询数据的语句
本文介绍了关系型数据库中的基本SQL查询语句,包括选择所有或特定列、带条件查询、排序、分组、过滤分组、表连接、限制记录数及子查询。SQL还支持窗口函数、存储过程等高级功能,是高效管理数据库的关键。建议深入学习SQL及相应数据库系统文档。
6 2
|
9天前
|
人工智能 Cloud Native 算法
数据之势丨AI时代,云原生数据库的最新发展趋势与进展
AI与云数据库的深度结合是数据库发展的必然趋势,基于AI能力的加持,云数据库未来可以实现更快速的查询和决策,帮助企业更好地利用海量数据进行业务创新和决策优化。
数据之势丨AI时代,云原生数据库的最新发展趋势与进展
|
25天前
|
关系型数据库 MySQL OLAP
PolarDB +AnalyticDB Zero-ETL :免费同步数据到ADB,享受数据流通新体验
Zero-ETL是阿里云瑶池数据库提供的服务,旨在简化传统ETL流程的复杂性和成本,提高数据实时性。降低数据同步成本,允许用户快速在AnalyticDB中对PolarDB数据进行分析,降低了30%的数据接入成本,提升了60%的建仓效率。 Zero-ETL特性包括免费的PolarDB MySQL联邦分析和PolarDB-X元数据自动同步,提供一体化的事务处理和数据分析,并能整合多个数据源。用户只需简单配置即可实现数据同步和实时分析。
|
6月前
|
关系型数据库 数据管理 Go
《PostgreSQL数据分区:原理与实战》
《PostgreSQL数据分区:原理与实战》
85 0
|
2月前
|
关系型数据库 分布式数据库 PolarDB
电子书阅读分享《PolarDB开发者大会:PolarDB在线数据实时分析加速》
电子书阅读分享《PolarDB开发者大会:PolarDB在线数据实时分析加速》
85 3
|
2月前
|
关系型数据库 分布式数据库 PolarDB
电子书阅读分享《PolarDB开发者大会:PolarDB在线数据实时分析加速》
电子书阅读分享《PolarDB开发者大会:PolarDB在线数据实时分析加速》
76 1

相关产品

  • 云原生数据库 PolarDB