Use COPY FREEZE in pgbench for faster benchmark table population.
authorTatsuo Ishii
Thu, 2 Sep 2021 01:39:09 +0000 (10:39 +0900)
committerTatsuo Ishii
Thu, 2 Sep 2021 01:39:09 +0000 (10:39 +0900)
While populating the pgbench_accounts table, plain COPY was
unconditionally used. By changing it to COPY FREEZE, the time for
VACUUM is significantly reduced, thus the total time of "pgbench -i"
is also reduced. This only happens if pgbench runs against PostgreSQL
14 or later because COPY FREEZE in previous versions of PostgreSQL does
not bring the benefit. Also if partitioning is used, COPY FREEZE
cannot be used. In this case plain COPY will be used too.

Author: Tatsuo Ishii
Discussion: https://postgr.es/m/20210308.143907.2014279678657453983[email protected]
Reviewed-by: Fabien COELHO, Laurenz Albe, Peter Geoghegan, Dean Rasheed
doc/src/sgml/ref/pgbench.sgml
src/bin/pgbench/pgbench.c

index 0c60077e1f9b8425f12b6355e805a7ab5ac9e783..0f432767c25872c636065cb145e9d342024b2376 100644 (file)
@@ -220,6 +220,9 @@ pgbench  options  d
             data is generated in pgbench client and then
             sent to the server. This uses the client/server bandwidth
             extensively through a COPY.
+            pgbench uses the FREEZE option with 14 or later
+            versions of PostgreSQL to speed up
+            subsequent VACUUM, unless partitions are enabled.
             Using g causes logging to print one message
             every 100,000 rows while generating data for the
             pgbench_accounts table.
index a33c91dcedaba92008310186b850924a43cafa87..4c9952a85a60ba89b7c3dd8d930dc4b11f0ce856 100644 (file)
@@ -4153,6 +4153,7 @@ initGenerateDataClientSide(PGconn *con)
    PGresult   *res;
    int         i;
    int64       k;
+   char        *copy_statement;
 
    /* used to track elapsed time and estimate of the remaining time */
    pg_time_usec_t start;
@@ -4199,7 +4200,15 @@ initGenerateDataClientSide(PGconn *con)
    /*
     * accounts is big enough to be worth using COPY and tracking runtime
     */
-   res = PQexec(con, "copy pgbench_accounts from stdin");
+
+   /* use COPY with FREEZE on v14 and later without partioning */
+   if (partitions == 0 && PQserverVersion(con) >= 140000)
+       copy_statement = "copy pgbench_accounts from stdin with (freeze on)";
+   else
+       copy_statement = "copy pgbench_accounts from stdin";
+
+   res = PQexec(con, copy_statement);
+
    if (PQresultStatus(res) != PGRES_COPY_IN)
    {
        pg_log_fatal("unexpected copy in result: %s", PQerrorMessage(con));