Avoid calling SetMatViewPopulatedState if possible

Started by cca5507about 2 months ago5 messageshackers
Jump to latest
#1cca5507
cca5507@qq.com

Hi,

During refresh matview, we call SetMatViewPopulatedState unconditionally even
if the value doesn't change. Attach a small patch to optimize it.

--
Regards,
ChangAo Chen

Attachments:

v1-0001-Avoid-calling-SetMatViewPopulatedState-if-possibl.patchapplication/octet-stream; charset=utf-8; name=v1-0001-Avoid-calling-SetMatViewPopulatedState-if-possibl.patchDownload+2-2
#2David Geier
geidav.pg@gmail.com
In reply to: cca5507 (#1)
Re: Avoid calling SetMatViewPopulatedState if possible

Hi,

On 10.04.2026 05:36, cca5507 wrote:

During refresh matview, we call SetMatViewPopulatedState unconditionally even
if the value doesn't change. Attach a small patch to optimize it.

Thanks for sharing this patch.

While being a simple patch, it would be good to know what actual use
cases this change improves on and by how much. Can you share a test case
and/or performance data?

--
David Geier

#3cca5507
cca5507@qq.com
In reply to: David Geier (#2)
Re: Avoid calling SetMatViewPopulatedState if possible

Hi,

Thanks for your reply!

While being a simple patch, it would be good to know what actual use
cases this change improves on and by how much. Can you share a test case
and/or performance data?

The improvement of performance is small, so it's hard to observe it. But I think
the patch is still useful because we can avoid generating dead pg_class tuple:

create table t(a int);
create materialized view m as select a from t;
create unique index on m(a);
select ctid from pg_class where relname = 'm';
refresh materialized view concurrently m;
select ctid from pg_class where relname = 'm';

Before the patch, the ctid will change every time we refresh the matview.

--
Regards,
ChangAo Chen

#4David Geier
geidav.pg@gmail.com
In reply to: cca5507 (#3)
Re: Avoid calling SetMatViewPopulatedState if possible

On 05.05.2026 13:58, cca5507 wrote:

While being a simple patch, it would be good to know what actual use
cases this change improves on and by how much. Can you share a test case
and/or performance data?

The improvement of performance is small, so it's hard to observe it. But I think
the patch is still useful because we can avoid generating dead pg_class tuple:

create table t(a int);
create materialized view m as select a from t;
create unique index on m(a);
select ctid from pg_class where relname = 'm';
refresh materialized view concurrently m;
select ctid from pg_class where relname = 'm';

Before the patch, the ctid will change every time we refresh the matview.

Yeah, that's kind of what I had in mind as I wasn't expecting the
performance to matter much here. Avoiding the bloat seems generally
reasonable.

But refreshing a materialized view doesn't only change relispopulated
but also columns like relfilenode, relpages, relhasindex, etc. Doesn't
changing these columns during REFRESH MATERIALIZED VIEW make your
optimization applicable in a lot less cases?

I'm actually wondering why it works at all, even in the example you
gave. Because I thought that even when nothing has changed the pg_class
row is updated for more columns than just relispopulated.

--
David Geier

#5cca5507
cca5507@qq.com
In reply to: David Geier (#4)
Re: Avoid calling SetMatViewPopulatedState if possible

But refreshing a materialized view doesn't only change relispopulated
but also columns like relfilenode, relpages, relhasindex, etc. Doesn't
changing these columns during REFRESH MATERIALIZED VIEW make your
optimization applicable in a lot less cases?

I don't think so. If we can skip SetMatViewPopulatedState(), we avoid generating
a dead pg_class tuple in all cases.

I'm actually wondering why it works at all, even in the example you
gave. Because I thought that even when nothing has changed the pg_class
row is updated for more columns than just relispopulated.

"refresh materialized view concurrently" is done by doing DELETE + INSERT
to the matview directly, so only relispopulated will change before the patch.
After the patch, the pg_class row don't change anymore.

--
Regards,
ChangAo Chen