Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8f42718

Browse files
jeff-daviscoreyhuinkerjeff-davis-aster
committed
Avoid unnecessary relation stats query in pg_dump.
The few fields we need can be easily collected in getTables() and getIndexes() and stored in RelStatsInfo. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reported-by: Andres Freund <andres@anarazel.de> Co-authored-by: Corey Huinker <corey.huinker@gmail.com> Co-authored-by: Jeff Davis <pgsql@j-davis.com> Discussion: https://postgr.es/m/CADkLM=f0a43aTd88xW4xCFayEF25g-7hTrHX_WhV40HyocsUGg@mail.gmail.com
1 parent 6c349d8 commit 8f42718

File tree

2 files changed

+64
-86
lines changed

2 files changed

+64
-86
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 60 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "common/connect.h"
5757
#include "common/int.h"
5858
#include "common/relpath.h"
59+
#include "common/shortest_dec.h"
5960
#include "compress_io.h"
6061
#include "dumputils.h"
6162
#include "fe_utils/option_utils.h"
@@ -524,6 +525,9 @@ main(int argc, char **argv)
524525
pg_logging_set_level(PG_LOG_WARNING);
525526
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_dump"));
526527

528+
/* ensure that locale does not affect floating point interpretation */
529+
setlocale(LC_NUMERIC, "C");
530+
527531
/*
528532
* Initialize what we need for parallel execution, especially for thread
529533
* support on Windows.
@@ -6814,7 +6818,8 @@ getFuncs(Archive *fout)
68146818
*
68156819
*/
68166820
static RelStatsInfo *
6817-
getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
6821+
getRelationStatistics(Archive *fout, DumpableObject *rel, int32 relpages,
6822+
float reltuples, int32 relallvisible, char relkind)
68186823
{
68196824
if (!fout->dopt->dumpStatistics)
68206825
return NULL;
@@ -6839,6 +6844,9 @@ getRelationStatistics(Archive *fout, DumpableObject *rel, char relkind)
68396844
dobj->components |= DUMP_COMPONENT_STATISTICS;
68406845
dobj->name = pg_strdup(rel->name);
68416846
dobj->namespace = rel->namespace;
6847+
info->relpages = relpages;
6848+
info->reltuples = reltuples;
6849+
info->relallvisible = relallvisible;
68426850
info->relkind = relkind;
68436851
info->postponed_def = false;
68446852

@@ -6874,6 +6882,8 @@ getTables(Archive *fout, int *numTables)
68746882
int i_relhasindex;
68756883
int i_relhasrules;
68766884
int i_relpages;
6885+
int i_reltuples;
6886+
int i_relallvisible;
68776887
int i_toastpages;
68786888
int i_owning_tab;
68796889
int i_owning_col;
@@ -6924,7 +6934,7 @@ getTables(Archive *fout, int *numTables)
69246934
"c.relowner, "
69256935
"c.relchecks, "
69266936
"c.relhasindex, c.relhasrules, c.relpages, "
6927-
"c.relhastriggers, "
6937+
"c.reltuples, c.relallvisible, c.relhastriggers, "
69286938
"c.relpersistence, "
69296939
"c.reloftype, "
69306940
"c.relacl, "
@@ -7088,6 +7098,8 @@ getTables(Archive *fout, int *numTables)
70887098
i_relhasindex = PQfnumber(res, "relhasindex");
70897099
i_relhasrules = PQfnumber(res, "relhasrules");
70907100
i_relpages = PQfnumber(res, "relpages");
7101+
i_reltuples = PQfnumber(res, "reltuples");
7102+
i_relallvisible = PQfnumber(res, "relallvisible");
70917103
i_toastpages = PQfnumber(res, "toastpages");
70927104
i_owning_tab = PQfnumber(res, "owning_tab");
70937105
i_owning_col = PQfnumber(res, "owning_col");
@@ -7134,6 +7146,9 @@ getTables(Archive *fout, int *numTables)
71347146

71357147
for (i = 0; i < ntups; i++)
71367148
{
7149+
float reltuples = strtof(PQgetvalue(res, i, i_reltuples), NULL);
7150+
int32 relallvisible = atoi(PQgetvalue(res, i, i_relallvisible));
7151+
71377152
tblinfo[i].dobj.objType = DO_TABLE;
71387153
tblinfo[i].dobj.catId.tableoid = atooid(PQgetvalue(res, i, i_reltableoid));
71397154
tblinfo[i].dobj.catId.oid = atooid(PQgetvalue(res, i, i_reloid));
@@ -7233,7 +7248,8 @@ getTables(Archive *fout, int *numTables)
72337248

72347249
/* Add statistics */
72357250
if (tblinfo[i].interesting)
7236-
getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relkind);
7251+
getRelationStatistics(fout, &tblinfo[i].dobj, tblinfo[i].relpages,
7252+
reltuples, relallvisible, tblinfo[i].relkind);
72377253

72387254
/*
72397255
* Read-lock target tables to make sure they aren't DROPPED or altered
@@ -7499,6 +7515,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
74997515
i_oid,
75007516
i_indrelid,
75017517
i_indexname,
7518+
i_relpages,
7519+
i_reltuples,
7520+
i_relallvisible,
75027521
i_parentidx,
75037522
i_indexdef,
75047523
i_indnkeyatts,
@@ -7552,6 +7571,7 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
75527571
appendPQExpBufferStr(query,
75537572
"SELECT t.tableoid, t.oid, i.indrelid, "
75547573
"t.relname AS indexname, "
7574+
"t.relpages, t.reltuples, t.relallvisible, "
75557575
"pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, "
75567576
"i.indkey, i.indisclustered, "
75577577
"c.contype, c.conname, "
@@ -7659,6 +7679,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
76597679
i_oid = PQfnumber(res, "oid");
76607680
i_indrelid = PQfnumber(res, "indrelid");
76617681
i_indexname = PQfnumber(res, "indexname");
7682+
i_relpages = PQfnumber(res, "relpages");
7683+
i_reltuples = PQfnumber(res, "reltuples");
7684+
i_relallvisible = PQfnumber(res, "relallvisible");
76627685
i_parentidx = PQfnumber(res, "parentidx");
76637686
i_indexdef = PQfnumber(res, "indexdef");
76647687
i_indnkeyatts = PQfnumber(res, "indnkeyatts");
@@ -7725,6 +7748,9 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
77257748
char contype;
77267749
char indexkind;
77277750
RelStatsInfo *relstats;
7751+
int32 relpages = atoi(PQgetvalue(res, j, i_relpages));
7752+
float reltuples = strtof(PQgetvalue(res, j, i_reltuples), NULL);
7753+
int32 relallvisible = atoi(PQgetvalue(res, j, i_relallvisible));
77287754

77297755
indxinfo[j].dobj.objType = DO_INDEX;
77307756
indxinfo[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, i_tableoid));
@@ -7759,7 +7785,8 @@ getIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
77597785
indexkind = RELKIND_PARTITIONED_INDEX;
77607786

77617787
contype = *(PQgetvalue(res, j, i_contype));
7762-
relstats = getRelationStatistics(fout, &indxinfo[j].dobj, indexkind);
7788+
relstats = getRelationStatistics(fout, &indxinfo[j].dobj, relpages,
7789+
reltuples, relallvisible, indexkind);
77637790

77647791
if (contype == 'p' || contype == 'u' || contype == 'x')
77657792
{
@@ -10383,18 +10410,6 @@ dumpComment(Archive *fout, const char *type,
1038310410
catalogId, subid, dumpId, NULL);
1038410411
}
1038510412

10386-
/*
10387-
* Tabular description of the parameters to pg_restore_relation_stats()
10388-
* param_name, param_type
10389-
*/
10390-
static const char *rel_stats_arginfo[][2] = {
10391-
{"relation", "regclass"},
10392-
{"version", "integer"},
10393-
{"relpages", "integer"},
10394-
{"reltuples", "real"},
10395-
{"relallvisible", "integer"},
10396-
};
10397-
1039810413
/*
1039910414
* Tabular description of the parameters to pg_restore_attribute_stats()
1040010415
* param_name, param_type
@@ -10419,30 +10434,6 @@ static const char *att_stats_arginfo[][2] = {
1041910434
{"range_bounds_histogram", "text"},
1042010435
};
1042110436

10422-
/*
10423-
* getRelStatsExportQuery --
10424-
*
10425-
* Generate a query that will fetch all relation (e.g. pg_class)
10426-
* stats for a given relation.
10427-
*/
10428-
static void
10429-
getRelStatsExportQuery(PQExpBuffer query, Archive *fout,
10430-
const char *schemaname, const char *relname)
10431-
{
10432-
resetPQExpBuffer(query);
10433-
appendPQExpBufferStr(query,
10434-
"SELECT c.oid::regclass AS relation, "
10435-
"current_setting('server_version_num') AS version, "
10436-
"c.relpages, c.reltuples, c.relallvisible "
10437-
"FROM pg_class c "
10438-
"JOIN pg_namespace n "
10439-
"ON n.oid = c.relnamespace "
10440-
"WHERE n.nspname = ");
10441-
appendStringLiteralAH(query, schemaname, fout);
10442-
appendPQExpBufferStr(query, " AND c.relname = ");
10443-
appendStringLiteralAH(query, relname, fout);
10444-
}
10445-
1044610437
/*
1044710438
* getAttStatsExportQuery --
1044810439
*
@@ -10454,21 +10445,22 @@ getAttStatsExportQuery(PQExpBuffer query, Archive *fout,
1045410445
const char *schemaname, const char *relname)
1045510446
{
1045610447
resetPQExpBuffer(query);
10457-
appendPQExpBufferStr(query,
10458-
"SELECT c.oid::regclass AS relation, "
10459-
"s.attname,"
10460-
"s.inherited,"
10461-
"current_setting('server_version_num') AS version, "
10462-
"s.null_frac,"
10463-
"s.avg_width,"
10464-
"s.n_distinct,"
10465-
"s.most_common_vals,"
10466-
"s.most_common_freqs,"
10467-
"s.histogram_bounds,"
10468-
"s.correlation,"
10469-
"s.most_common_elems,"
10470-
"s.most_common_elem_freqs,"
10471-
"s.elem_count_histogram,");
10448+
appendPQExpBuffer(query,
10449+
"SELECT c.oid::regclass AS relation, "
10450+
"s.attname,"
10451+
"s.inherited,"
10452+
"'%u'::integer AS version, "
10453+
"s.null_frac,"
10454+
"s.avg_width,"
10455+
"s.n_distinct,"
10456+
"s.most_common_vals,"
10457+
"s.most_common_freqs,"
10458+
"s.histogram_bounds,"
10459+
"s.correlation,"
10460+
"s.most_common_elems,"
10461+
"s.most_common_elem_freqs,"
10462+
"s.elem_count_histogram,",
10463+
fout->remoteVersion);
1047210464

1047310465
if (fout->remoteVersion >= 170000)
1047410466
appendPQExpBufferStr(query,
@@ -10521,34 +10513,21 @@ appendNamedArgument(PQExpBuffer out, Archive *fout, const char *argname,
1052110513
* Append a formatted pg_restore_relation_stats statement.
1052210514
*/
1052310515
static void
10524-
appendRelStatsImport(PQExpBuffer out, Archive *fout, PGresult *res)
10516+
appendRelStatsImport(PQExpBuffer out, Archive *fout, const RelStatsInfo *rsinfo)
1052510517
{
10526-
const char *sep = "";
10518+
const char *qualname = fmtQualifiedId(rsinfo->dobj.namespace->dobj.name, rsinfo->dobj.name);
10519+
char reltuples_str[FLOAT_SHORTEST_DECIMAL_LEN];
1052710520

10528-
if (PQntuples(res) == 0)
10529-
return;
10521+
float_to_shortest_decimal_buf(rsinfo->reltuples, reltuples_str);
1053010522

1053110523
appendPQExpBufferStr(out, "SELECT * FROM pg_catalog.pg_restore_relation_stats(\n");
10532-
10533-
for (int argno = 0; argno < lengthof(rel_stats_arginfo); argno++)
10534-
{
10535-
const char *argname = rel_stats_arginfo[argno][0];
10536-
const char *argtype = rel_stats_arginfo[argno][1];
10537-
int fieldno = PQfnumber(res, argname);
10538-
10539-
if (fieldno < 0)
10540-
pg_fatal("relation stats export query missing field '%s'",
10541-
argname);
10542-
10543-
if (PQgetisnull(res, 0, fieldno))
10544-
continue;
10545-
10546-
appendPQExpBufferStr(out, sep);
10547-
appendNamedArgument(out, fout, argname, PQgetvalue(res, 0, fieldno), argtype);
10548-
10549-
sep = ",\n";
10550-
}
10551-
appendPQExpBufferStr(out, "\n);\n");
10524+
appendPQExpBuffer(out, "\t'relation', '%s'::regclass,\n", qualname);
10525+
appendPQExpBuffer(out, "\t'version', '%u'::integer,\n",
10526+
fout->remoteVersion);
10527+
appendPQExpBuffer(out, "\t'relpages', '%d'::integer,\n", rsinfo->relpages);
10528+
appendPQExpBuffer(out, "\t'reltuples', '%s'::real,\n", reltuples_str);
10529+
appendPQExpBuffer(out, "\t'relallvisible', '%d'::integer\n);\n",
10530+
rsinfo->relallvisible);
1055210531
}
1055310532

1055410533
/*
@@ -10643,15 +10622,11 @@ dumpRelationStats(Archive *fout, const RelStatsInfo *rsinfo)
1064310622
tag = createPQExpBuffer();
1064410623
appendPQExpBufferStr(tag, fmtId(dobj->name));
1064510624

10646-
query = createPQExpBuffer();
1064710625
out = createPQExpBuffer();
1064810626

10649-
getRelStatsExportQuery(query, fout, dobj->namespace->dobj.name,
10650-
dobj->name);
10651-
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);
10652-
appendRelStatsImport(out, fout, res);
10653-
PQclear(res);
10627+
appendRelStatsImport(out, fout, rsinfo);
1065410628

10629+
query = createPQExpBuffer();
1065510630
getAttStatsExportQuery(query, fout, dobj->namespace->dobj.name,
1065610631
dobj->name);
1065710632
res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK);

src/bin/pg_dump/pg_dump.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ typedef struct _tableInfo
328328
Oid owning_tab; /* OID of table owning sequence */
329329
int owning_col; /* attr # of column owning sequence */
330330
bool is_identity_sequence;
331-
int relpages; /* table's size in pages (from pg_class) */
331+
int32 relpages; /* table's size in pages (from pg_class) */
332332
int toastpages; /* toast table's size in pages, if any */
333333

334334
bool interesting; /* true if need to collect more data */
@@ -438,6 +438,9 @@ typedef struct _indexAttachInfo
438438
typedef struct _relStatsInfo
439439
{
440440
DumpableObject dobj;
441+
int32 relpages;
442+
float reltuples;
443+
int32 relallvisible;
441444
char relkind; /* 'r', 'm', 'i', etc */
442445
bool postponed_def; /* stats must be postponed into post-data */
443446
} RelStatsInfo;

0 commit comments

Comments
 (0)