PostgreSQL创建字段设置默认值并且不锁表

1创建测试表

drop table if exists test009;
create table test009(
	objectid bigint not null,	
	name text not null,	
	--flag integer default(2) not null,  --用于演示添加的字段
	constraint pk_test009_objectid primary key (objectid) with (fillfactor=100)
) with (fillfactor=100);

2 插入测试数据1000W

drop function if exists gen_random(int,int);
create or replace function gen_random(int,int)
	returns text
as $$
	select string_agg(((random()*(9-0)+0 )::integer)::text , '')  from generate_series(1,(random()*($2-$1)+$1)::integer);
$$ language sql;


do $$
	declare 
		v_dys integer[];
	begin
		for i in 1..1000 loop
			insert into test009
					select (id + (i-1)*10000),gen_random(8,32) from generate_series(1,10000) as id;
			raise notice  '%', i;
		end loop;
	end;
$$;

analyze verbose test009;
select count(*) from test009;

3 直接添加字段并设置默认值会锁表

设置默认值后实际上也是更新了数据


select ctid from test009 order by objectid limit 100;
alter table test009
	add column flag integer default(2) not null;
--注意这个表太小,修改完成后被autovacuum立即处理了,测试前先关闭autovacuum或使用大表
select ctid from test009 order by objectid limit 100;
alter table test009
	drop column flag;

完成以后也要vacuum,vacuum会锁表.或者等待autovacuum处理

4 先添加字段但不设置默认值

alter table test009
	add column flag integer;

然后更新flag为默认值

do $$
	declare 
		v_currentid bigint;
		v_rec record;
	begin
		v_currentid := -1; 
		loop
			for v_rec in (with cte as(
				select objectid from test009 where objectid>v_currentid order by objectid limit 1000
			)select array_agg(objectid) as ids from cte) loop
				update test009 set flag=2 where objectid=any(v_rec.ids);
				v_currentid := v_rec.ids[1000];
			end loop;			
			--raise notice  '%', v_currentid;
			if( v_currentid is null ) then
				return;
			end if;
		end loop;
	end;
$$;
--在执行过程中在另一过程执行可以查出数据,只是较慢
select count(*) from test009;

4 最后一步

--设置为not null
alter table test009
	alter column flag set not null;
--因为更新了大量的数据,所以需要vacuum一下表
--注意 alter table test009 add column flag integer default(2) not null;也更新了表,完成以后也要vacuum
vacuum  freeze verbose analyze test009;

猜你喜欢

转载自blog.csdn.net/kmblack1/article/details/82803996