2017-05-15 27 views
1

我想通过使所有表UNLOGGED减少本地测试执行时间。我想编写sql脚本,它将在所有转换后运行,并使它们成为UNLOGGED。但是我发现问题表与FK相互关联,所以postgresql如果它与其他表不是UNLOGGED的其他表相关联,则禁止创建表UNLOGGED(通过ALTER)。使数据库中的所有表UNLOGGED

有没有更好的方法,然后以正确的顺序列出所有的ALTER - 我有更多的150表?例如,将其应用于数据库级别。

+0

所有试验后,我设法让所有表格都没有记录,但是执行测试的速度减慢了〜20%。所以,不要做到这一点。 – mshutov

回答

1

你必须以正确的顺序改变他们,我很害怕。 您可以选择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" 

但你起不到任何我相信的方式。

另外不要忘记,不洁的关机或失败后,未记录的表将被截断。

最后一点,你说“所有的转换后” - 如果你创建,转换等,也许你应该刚刚创建它们未登录..

+0

谢谢。将在我的环境中尝试此解决方案 关于转换 - 它们针对生产和测试均执行不变,以确保开发,测试和产品环境下的DB方案相同。测试数据库中的表也在每次测试之前完全分离,因此腐败不成问题。 – mshutov

+0

是有道理的 - 我不得不问,因为它从帖子中不明显,似乎很奇怪:) udachi! –

+0

您对' - 通过oid逻辑推理,您应该从最新添加的对象开始到最早 - 当然它不保证任何事情'的评论是正确的。最后,我打印了报表并重新排序。 不幸的是,执行测试减慢了〜20% – mshutov

1

我会删除并重新创建所有外键?您可以自动执行此操作。

以下查询将为所有外键生成必要的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 之前你放弃他们;)

+0

谢谢。有趣的方法。也会尝试一下。 – mshutov

+0

使用VaoTsun变种,因为它更容易申请。不幸的是,没有得到改善 – mshutov

相关问题