PostgreSQL pgbench SQL RT 与 事务RT 浅析

背景

使用pgbench测试数据库性能时,在输出的报告中,可以输出事务的平均RT,以及单条SQL的平均RT。

那么这两个有什么分别呢?

每行代表一个线程,被填充了颜色的部分表示从客户端发起SQL到SQL返回的时间窗口,没有填充颜色的部分表示线程的空闲时间。

如何统计事务 平均RT :
执行的事务数/总的测试时长

如何统计SQL 平均RT :
每条SQL的执行时长累加/总的SQL执行次数

从计算公式以及图例来分析,显然SQL的平均RT会更低,因为没有计算线程的空闲时间。

特别是pgbench与数据库在同一主机进行测试时,全力压测(CPU吃满)的情况下,PGBENCH的线程等待(空闲)时间会更明显,SQL的RT会比事务的RT低很多。

那么哪个值更能代表数据库的处理能力呢?

SQL平均RT可以代表数据库的真实处理能力,而事务RT则是代表从客户端到数据库端作为一个整体来看待的事务处理能力(包括客户端的处理时间,数据库的处理时间,以及网络传输时间)。

pgbench 相关源码浅析

不加 -r 参数

返回样例如下

transaction type: TPC-B (sort of)
scaling factor: 100
query mode: prepared
number of clients: 10
number of threads: 10
duration: 10 s
number of transactions actually processed: 29032
latency average: 3.442 ms
latency stddev: 74.879 ms
tps = 2902.936994 (including connections establishing)
tps = 2903.710037 (excluding connections establishing)

代码如下
打印事务RT(或脚本RT)为 测试的持续时长 除以 总的事务数

                /* only an average latency computed from the duration is available */
                printf("latency average: %.3f ms\n",
                           1000.0 * duration * nclients / total->cnt);

加 -r 参数

  -r, --report-latencies   report average latency per command

返回样例如下

transaction type: TPC-B (sort of)
scaling factor: 100
query mode: prepared
number of clients: 10
number of threads: 10
duration: 10 s
number of transactions actually processed: 22000
latency average: 5.634 ms
latency stddev: 191.632 ms
tps = 1773.794731 (including connections establishing)
tps = 1774.193277 (excluding connections establishing)
statement latencies in milliseconds:
        0.003053        \set nbranches 1 * :scale
        0.000832        \set ntellers 10 * :scale
        0.000661        \set naccounts 100000 * :scale
        0.001120        \setrandom aid 1 :naccounts
        0.000909        \setrandom bid 1 :nbranches
        0.000742        \setrandom tid 1 :ntellers
        0.000773        \setrandom delta -5000 5000
        0.053747        BEGIN;
        0.183235        UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
        0.092281        SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
        0.113678        UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
        0.155755        UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
        0.088806        INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
        4.929969        END;

代码浅析
参数

-r
                        case 'r':
                                benchmarking_option_set = true;
                                per_script_stats = true;
                                is_latencies = true;
                                break;

语句开始时间

        instr_time      stmt_begin;             /* used for measuring statement latencies */
......
        /* Record statement start time if per-command latencies are requested */
        if (is_latencies)
                INSTR_TIME_SET_CURRENT(st->stmt_begin);

累加语句的执行时间

                /*
                 * command finished: accumulate per-command execution times in
                 * thread-local data structure, if per-command latencies are requested
                 */
                if (is_latencies)
                {
                        if (INSTR_TIME_IS_ZERO(now))
                                INSTR_TIME_SET_CURRENT(now);

                        /* XXX could use a mutex here, but we choose not to */
                        addToSimpleStats(&commands[st->state]->stats,
                                                         INSTR_TIME_GET_DOUBLE(now) -
                                                         INSTR_TIME_GET_DOUBLE(st->stmt_begin));
                }
......
/*
 * Accumulate one value into a SimpleStats struct.
 */
static void
addToSimpleStats(SimpleStats *ss, double val)
{
        if (ss->count == 0 || val < ss->min)
                ss->min = val;
        if (ss->count == 0 || val > ss->max)
                ss->max = val;
        ss->count++;
        ss->sum += val;
        ss->sum2 += val * val;
}

数据结构

/*
 * Simple data structure to keep stats about something.
 *
 * XXX probably the first value should be kept and used as an offset for
 * better numerical stability...
 */
typedef struct SimpleStats
{
        int64           count;                  /* how many values were encountered */
        double          min;                    /* the minimum seen */
        double          max;                    /* the maximum seen */
        double          sum;                    /* sum of values */
        double          sum2;                   /* sum of squared values */
} SimpleStats;

/*
 * Data structure to hold various statistics: per-thread and per-script stats
 * are maintained and merged together.
 */
typedef struct StatsData
{
        long            start_time;             /* interval start time, for aggregates */
        int64           cnt;                    /* number of transactions */
        int64           skipped;                /* number of transactions skipped under --rate
                                                                 * and --latency-limit */
        SimpleStats latency;
        SimpleStats lag;
} StatsData;

打印语句的RT (语句的累计时间 除以 语句的调用次数)

                        /* Report per-command latencies */
                        if (is_latencies)
                        {
                                Command   **commands;

                                printf(" - statement latencies in milliseconds:\n");

                                for (commands = sql_script[i].commands;
                                         *commands != NULL;
                                         commands++)
                                        printf("   %11.3f  %s\n",
                                                   1000.0 * (*commands)->stats.sum /
                                                   (*commands)->stats.count,
                                                   (*commands)->line);
                        }

Count

时间: 2024-11-01 02:51:49

PostgreSQL pgbench SQL RT 与 事务RT 浅析的相关文章

SQL Server 中WITH (NOLOCK)浅析

原文:SQL Server 中WITH (NOLOCK)浅析 概念介绍    开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种.它等同于 READUNCOMMITTED . 具体的功能作用如下所示(摘自MSDN):    1: 指定允许脏读.不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据.允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改.这

PostgreSQL 9.6 平滑fsync, write原理浅析

PostgreSQL 9.6 平滑fsync, write原理浅析 作者 digoal 日期 2016-10-06 标签 PostgreSQL , 9.6 , 平滑 fsync , write , smooth fsync 背景 汽车换挡是否平顺,通常取决于档位数,或者换挡技术. 档位数越多,换挡时感觉会约平顺,档位数较少的情况下,换挡可能会有比较明显的顿挫感觉. 数据库也一样,有些时候可能就会出现卡顿的现象,比如尖锐(堆积)的IO需求时. 本文将给大家介绍9.6在fsync, write方面的

数据库-sql server 2005 事务日志删除问题

问题描述 sql server 2005 事务日志删除问题 sql server 2005 事务日志 删除对数据库有多大影响? 如何删除sql server 2005 事务日志 如何做到定期删除半年前的,保留半年的事务日志? 解决方案 如果你的数据库是full模式,那需要先做完整备份,再定期做日志备份,这样才能截断日志 如果数据库是simple模式,就不存在截断日志的问题

SQL Server 为什么事务日志自动增长会降低你的性能

原文地址:点击打开链接   在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations).很多运行的数据库服务器,对于事务日志,用的都是默认的日志文件大小和自动增长设置.人们有时会很依赖自动增长机制,因为它们刚好能正常工作.当然,如果它正常工作的话,你不必太关注它,但很快你会发现会有问题出现.   只依赖于事务日志的自动增长机制总不是个好主意.首先它会导致严重的日志碎片(Log Fragmentation),在

SQL Server-聚焦事务、隔离级别详解(二十九)

前言 事务一直以来是我最薄弱的环节,也是我打算重新学习SQL Server的出发点,关于SQL Server中事务将分为几节来进行阐述,Always to review the basics.  事务简介 事务是一个工作单元,可能包含查询和修改数据以及修改数据定义等多个活动.我们可以显式或隐式的定义事务边界.可以使用BEGIN TRAN或者BEGIN TRANSACTION语句显式的定义事务的开始.如果希望提交事务,可以使用COMMIT TRAN语句显式的定义事务结束.如果不希望提交事务(即要撤

PostgreSQL serializable read only deferrable事务的用法背景

在开始讲serializable read only deferrable用法前,需要先了解一下serializable隔离级别.https://wiki.postgresql.org/wiki/Serializablehttp://www.postgresql.org/docs/9.5/static/transaction-iso.html#XACT-SERIALIZABLEhttp://blog.163.com/digoal@126/blog/static/16387704020131117

PostgreSQL 同步流复制原理和代码浅析

数据库ACID中的持久化如何实现 数据库ACID里面的D,持久化. 指的是对于用户来说提交的事务,数据是可靠的,即使数据库crash了,在硬件完好的情况下,也能恢复回来.PostgreSQL是怎么做到的呢,看一幅图,画得比较丑,凑合看吧.假设一个事务,对数据库做了一些操作,并且产生了一些脏数据,首先这些脏数据会在数据库的shared buffer中.同时,产生这些脏数据的同时也会产生对应的redo信息,产生的REDO会有对应的LSN号(你可以理解为REDO 的虚拟地址空间的一个唯一的OFFSET

MS SQL Server数据库事务锁机制分析

server|数据|数据库 锁是网络数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性.各种大型数据库所采用的锁的基本理论是一致的,但在具体实现上各有差别.目前,大多数数据库管理系统都或多或少具有自我调节.自我管理的功能,因此很多用户实际上不清楚锁的理论和所用数据库中锁的具体实现. Microsoft SQL Server(以下简称SQL Server)作为一种中小型数据库管理系统,已经得到了广泛的应用,该系统更强调由系统来管理锁.在用户有SQL请求时,系统分析请求,自

MS SQL Server的事务日志简介一览

交易日志,或称事务日志(Transaction logs)是数据库结构中非常重要但又经常被忽略的部分.由于它并不像数据库中的schema那样活跃,因此很少有人关注交易日志. 交易日志是针对数据库改变所做的记录,它可以记录针对数据库的任何操作,并将记录结果保存在独立的文件中.对于任何每一个交易过程,交易日志都有非常全面的记录,根据这些记录可以将数据文件恢复成交易前的状态.从交易动作开始,交易日志就处于记录状态,交易过程中对数据库的任何操作都在记录范围,直到用户点击提交或后退后才结束记录.每个数据库