我正在尝试在postgres中复制一个大表(〜4000万行,超过100列),其中很多列都已建立索引。目前,我使用以下SQL:
CREATE TABLE <tablename>_copy (LIKE <tablename> INCLUDING ALL); INSERT INTO <tablename>_copy SELECT * FROM <tablename>;
此方法有两个问题:
表的大小使索引成为实时问题。这也使得转储到文件然后重新注册变得不可行。我也没有命令行的优势。我需要在SQL中执行此操作。
我想做的就是要么用一些奇迹命令直接复制一个精确的副本,要么(如果不可能的话)复制带有所有约束但没有索引的表,并确保它们是“精神上”的约束(aka SERIAL列的新计数器)。然后使用a复制所有数据,SELECT *然后复制所有索引。
SELECT *
资料来源
有关数据库复制的堆栈溢出问题:这不是我要问的三个原因
pg_dump -t x2 | sed 's/x2/x3/g' | psql
default nextval('x1_id_seq'::regclass)
好吧,不幸的是,您将不得不手工做一些这样的事情。但这一切都可以通过psql之类的方法完成。第一个命令很简单:
select * into newtable from oldtable
这将使用旧表的数据创建新表,但不使用索引。然后,您必须自己创建索引和序列等。您可以使用以下命令获取表上所有索引的列表:
select indexdef from pg_indexes where tablename='oldtable';
然后运行psql -E访问您的数据库,并使用\ d查看旧表。然后,您可以修改这两个查询以获取有关序列的信息:
SELECT c.oid, n.nspname, c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname ~ '^(oldtable)$' AND pg_catalog.pg_table_is_visible(c.oid) ORDER BY 2, 3; SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef), a.attnotnull, a.attnum FROM pg_catalog.pg_attribute a WHERE a.attrelid = '74359' AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum;
将上面的74359替换为从上一个查询中获得的oid。