Enable parallelism in REFRESH MATERIALIZED VIEW.
authorThomas Munro <[email protected]>
Wed, 17 Mar 2021 00:43:08 +0000 (13:43 +1300)
committerThomas Munro <[email protected]>
Wed, 17 Mar 2021 02:04:17 +0000 (15:04 +1300)
Pass CURSOR_OPT_PARALLEL_OK to pg_plan_query() so that parallel plans
are considered when running the underlying SELECT query.  This wasn't
done in commit e9baa5e9, which did this for CREATE MATERIALIZED VIEW,
because it wasn't yet known to be safe.

Since REFRESH always inserts into a freshly created table before later
merging or swapping the data into place with separate operations, we can
enable such plans here too.

Author: Bharath Rupireddy <[email protected]>
Reviewed-by: Hou, Zhijie <[email protected]>
Reviewed-by: Luc Vlaming <[email protected]>
Reviewed-by: Thomas Munro <[email protected]>
Discussion: https://postgr.es/m/CALj2ACXg-4hNKJC6nFnepRHYT4t5jJVstYvri%2BtKQHy7ydcr8A%40mail.gmail.com

doc/src/sgml/parallel.sgml
src/backend/commands/matview.c
src/test/regress/expected/write_parallel.out
src/test/regress/sql/write_parallel.sql

index cec1329e259237ce02a9cc36f2d8caff3fc52556..330c06b608f36af2cf0b31d2c25d6ab053e5e8e1 100644 (file)
@@ -144,11 +144,27 @@ EXPLAIN SELECT * FROM pgbench_accounts WHERE filler LIKE '%x%';
         The query writes any data or locks any database rows. If a query
         contains a data-modifying operation either at the top level or within
         a CTE, no parallel plans for that query will be generated.  As an
-        exception, the commands <literal>CREATE TABLE ... AS</literal>, <literal>SELECT
-        INTO</literal>, and <literal>CREATE MATERIALIZED VIEW</literal> which create a new
-        table and populate it can use a parallel plan. Another exception is the command
-        <literal>INSERT INTO ... SELECT ...</literal> which can use a parallel plan for
-        the underlying <literal>SELECT</literal> part of the query.
+        exception, the following commands which create a new table and populate
+        it can use a parallel plan for the underlying <literal>SELECT</literal>
+        part of the query:
+
+        <itemizedlist>
+          <listitem>
+            <para><command>CREATE TABLE ... AS</command></para>
+          </listitem>
+          <listitem>
+            <para><command>SELECT INTO</command></para>
+          </listitem>
+          <listitem>
+            <para><command>INSERT INTO ... SELECT</command></para>
+          </listitem>
+          <listitem>
+            <para><command>CREATE MATERIALIZED VIEW</command></para>
+          </listitem>
+          <listitem>
+            <para><command>REFRESH MATERIALIZED VIEW</command></para>
+          </listitem>
+        </itemizedlist>
       </para>
     </listitem>
 
index c5c25ce11d5e860038cd78c9af20ec588091f56d..172ec6e98284129a5bf20a90a920e624e775a88f 100644 (file)
@@ -402,7 +402,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
    CHECK_FOR_INTERRUPTS();
 
    /* Plan the query which will generate data for the refresh. */
-   plan = pg_plan_query(query, queryString, 0, NULL);
+   plan = pg_plan_query(query, queryString, CURSOR_OPT_PARALLEL_OK, NULL);
 
    /*
     * Use a snapshot with an updated command ID to ensure this query sees
index 77705f9a70974e6f2985aa0618626e5b8f3d579a..dc0c4ba587e16b46b727e5912aa07092cbc0adc6 100644 (file)
@@ -58,6 +58,9 @@ explain (costs off) create materialized view parallel_mat_view as
 
 create materialized view parallel_mat_view as
     select length(stringu1) from tenk1 group by length(stringu1);
+create unique index on parallel_mat_view(length);
+refresh materialized view parallel_mat_view;
+refresh materialized view concurrently parallel_mat_view;
 drop materialized view parallel_mat_view;
 prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1);
 explain (costs off) create table parallel_write as execute prep_stmt;
index a5d63112c96d4ab83a701218f59144723b0d71db..ae660dc2265d8a508650f5564c4397024783c9d1 100644 (file)
@@ -30,6 +30,9 @@ explain (costs off) create materialized view parallel_mat_view as
     select length(stringu1) from tenk1 group by length(stringu1);
 create materialized view parallel_mat_view as
     select length(stringu1) from tenk1 group by length(stringu1);
+create unique index on parallel_mat_view(length);
+refresh materialized view parallel_mat_view;
+refresh materialized view concurrently parallel_mat_view;
 drop materialized view parallel_mat_view;
 
 prepare prep_stmt as select length(stringu1) from tenk1 group by length(stringu1);