From 2c03dbd19ea485cccf8e0ec348a5710e196a3d7c Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Wed, 21 Apr 2021 07:31:25 +0530 Subject: [PATCH v1] Skip VACUUM/ANALYZE of repeated relations Skip vacuuming/analyzing of repeated relations to avoid unnecessary processing. We do this only when no explicit columns are specified, for instance, "VACUUM/ANALYZE foo, foo;". When columns are specified along with relations i.e. "VACUUM/ANALYZE foo(col1), foo(col2);", we don't want to further optimize the cases when col1 = col2. --- src/backend/commands/vacuum.c | 20 +++++++++++++++++++- src/test/regress/expected/vacuum.out | 2 +- src/test/regress/sql/vacuum.sql | 2 +- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 39df05c735..09d7971b15 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -438,6 +438,7 @@ vacuum(List *relations, VacuumParams *params, PG_TRY(); { ListCell *cur; + List *relids = NULL; in_vacuum = true; VacuumCostActive = (VacuumCostDelay > 0); @@ -456,6 +457,16 @@ vacuum(List *relations, VacuumParams *params, { VacuumRelation *vrel = lfirst_node(VacuumRelation, cur); + /* + * Skip VACUUM/ANALYZE of repeated relations. We do this only when + * no explicit columns are specified, for instance, "VACUUM/ANALYZE + * foo, foo;". When columns are specified along with relations + * i.e. "VACUUM/ANALYZE foo(col1), foo(col2);", we don't want to + * further optimize the cases when col1 = col2. + */ + if (vrel->va_cols == NULL && list_member_oid(relids, vrel->oid)) + continue; + if (params->options & VACOPT_VACUUM) { if (!vacuum_rel(vrel->oid, vrel->relation, params)) @@ -488,11 +499,18 @@ vacuum(List *relations, VacuumParams *params, /* * If we're not using separate xacts, better separate the * ANALYZE actions with CCIs. This avoids trouble if user - * says "ANALYZE t, t". + * says "ANALYZE t(col1), t(col2)". */ CommandCounterIncrement(); } } + + /* + * Remember the VACUUMed/ANALYZEed relation only when no explicit + * columns are specified. + */ + if (vrel->va_cols == NULL) + relids = lappend_oid(relids, vrel->oid); } } PG_FINALLY(); diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index 90cea6caa8..a67c56371d 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -218,7 +218,7 @@ ANALYZE vactst (i), vacparted (does_not_exist); ERROR: column "does_not_exist" of relation "vacparted" does not exist ANALYZE vactst, vactst; BEGIN; -- ANALYZE behaves differently inside a transaction block -ANALYZE vactst, vactst; +ANALYZE vactst (i), vactst (i); COMMIT; -- parenthesized syntax for ANALYZE ANALYZE (VERBOSE) does_not_exist; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 93fd258fc0..7daa3a7723 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -183,7 +183,7 @@ ANALYZE vactst, does_not_exist, vacparted; ANALYZE vactst (i), vacparted (does_not_exist); ANALYZE vactst, vactst; BEGIN; -- ANALYZE behaves differently inside a transaction block -ANALYZE vactst, vactst; +ANALYZE vactst (i), vactst (i); COMMIT; -- parenthesized syntax for ANALYZE -- 2.25.1