我想通过使所有表UNLOGGED
减少本地测试执行时间。我想编写sql脚本,它将在所有转换后运行,并使它们成为UNLOGGED
。但是我发现问题表与FK
相互关联,所以postgresql如果它与其他表不是UNLOGGED
的其他表相关联,则禁止创建表UNLOGGED
(通过ALTER
)。使数据库中的所有表UNLOGGED
有没有更好的方法,然后以正确的顺序列出所有的ALTER
- 我有更多的150表?例如,将其应用于数据库级别。
我想通过使所有表UNLOGGED
减少本地测试执行时间。我想编写sql脚本,它将在所有转换后运行,并使它们成为UNLOGGED
。但是我发现问题表与FK
相互关联,所以postgresql如果它与其他表不是UNLOGGED
的其他表相关联,则禁止创建表UNLOGGED
(通过ALTER
)。使数据库中的所有表UNLOGGED
有没有更好的方法,然后以正确的顺序列出所有的ALTER
- 我有更多的150表?例如,将其应用于数据库级别。
你必须以正确的顺序改变他们,我很害怕。 您可以选择https://www.postgresql.org/docs/current/static/catalog-pg-constraint.html和环路第一引用表,然后更改休息:
begin;
do
$$
declare
_r record;
_t text;
begin
for _r in (
select relname,conrelid
from pg_constraint
join pg_class c on c.oid = conrelid
where confkey is not null
order by conrelid desc
-- Order by oid with logic that you should start from latest added objects to earliest - of course it does not garantee anything
) loop
_t := format('alter table %I set unlogged',_r.relname);
raise info '%',_t;
execute _t;
end loop;
for _r in (select tablename from pg_tables where tablename like 's%' and schemaname = 'public') loop
_t := format('alter table %I set unlogged',_r.tablename);
raise info '%',_t;
execute _t;
end loop;
end;
$$
;
rollback;
通过各种手段,如果你有递归FK它将会失败:
t=# create table s134(i int primary key, e int);
CREATE TABLE
t=# create table s135(i int references s134(i), e int primary key);
CREATE TABLE
t=# alter table s134 add constraint c1 foreign key (e) references s135(e);
ALTER TABLE
t=# alter table s134 set unlogged;
ERROR: could not change table "s134" to unlogged because it references logged table "s135"
t=# alter table s135 set unlogged;
ERROR: could not change table "s135" to unlogged because it references logged table "s134"
但你起不到任何我相信的方式。
另外不要忘记,不洁的关机或失败后,未记录的表将被截断。
最后一点,你说“所有的转换后” - 如果你创建,转换等,也许你应该刚刚创建它们未登录..
我会删除并重新创建所有外键?您可以自动执行此操作。
以下查询将为所有外键生成必要的DDL语句。您需要将输出保存到文件中,以后可以使用该文件恢复所有外键。
select format('alter table %I.%I add constraint %I ', ns.nspname, tb.relname, conname)||
pg_get_constraintdef(c.oid, true)||';' as ddl
from pg_constraint c
join pg_class tb on tb.oid = c.conrelid
join pg_namespace ns on ns.oid = tb.relnamespace
where ns.nspname not in ('pg_catalog', 'information_schema')
and ns.nspname not like 'pg_temp%'
and c.contype in ('f')
然后生成一个脚本,删除所有的约束:
select format('alter table %I.%I drop constraint %I cascade;', ns.nspname, tb.relname, c.conname) as ddl
from pg_constraint c
join pg_class tb on tb.oid = c.conrelid
join pg_namespace ns on ns.oid = tb.relnamespace
where ns.nspname not in ('pg_catalog', 'information_schema')
and ns.nspname not like 'pg_temp%'
and c.contype in ('f');
当然,你必须运行查询生成FKS 之前你放弃他们;)
所有试验后,我设法让所有表格都没有记录,但是执行测试的速度减慢了〜20%。所以,不要做到这一点。 – mshutov