DROP TABLE IF EXISTS bench_b, bench_a; CREATE UNLOGGED TABLE bench_a (id text, c text, pad text, v int) WITH (autovacuum_enabled = off); CREATE UNLOGGED TABLE bench_b (id text, c text, pad text, v int) WITH (autovacuum_enabled = off); INSERT INTO bench_a SELECT repeat('x', 100), repeat('x', 100), repeat('x', 100), CASE WHEN g %5 < 3 then NULL ELSE random(2::int, 10002) END as v FROM generate_series(1, 2_000_000) g; CREATE INDEX ON bench_a(v); UPDATE bench_a SET v = 1 WHERE v IS NULL; INSERT INTO bench_b SELECT repeat('x', 100), repeat('x', 100), repeat('x', 100), CASE WHEN g %5 < 1 then NULL ELSE random(2::int, 10002) END as v FROM generate_series(1, 2_000_000) g; UPDATE bench_b SET v = 1 WHERE v IS NULL; \timing -- first Time run: 481.565 ms -- after several times run Time: 1.598 ms BEGIN; ALTER TABLE bench_a ALTER COLUMN v SET NOT NULL; ROLLBACK; -- first time Time run: 484.124 ms -- after several times Time: 213.361 ms BEGIN; ALTER TABLE bench_b ALTER COLUMN v SET NOT NULL; ROLLBACK;