我有一个包含 3 亿行(和 10 列)的表,我想将其克隆到同一服务器中。
到目前为止我已经尝试过
START TRANSACTION ISOLATION LEVEL SERIALIZABLE;
CREATE TABLE cloned_table AS (SELECT * FROM big_table);
COMMIT;
但是,在调用
COMMIT;
之后,MonetDB 开始创建一个巨大的事务日志,阻塞所有其他查询。
这是操作时的状态
如您所见,最糟糕的部分是 MonetDB 正在使用磁盘,即使有大量可用内存。
最好的方法是什么??
MonetDB 必须为此查询将大量数据写入磁盘:一次是为了保护日志文件,一次是为了保存新表的数据。可用内存不会改变这个事实。 (大内存主要有利于产生大量中间数据的查询,但这里不是这种情况)。
巨大的日志文件是由事务的大小引起的,即 300 行 * 10 列 * 。 MonetDB 将一笔交易的所有数据记录在一个文件中。
由于您要复制大型表,因此建议将表创建和数据插入分开到各自的事务中。 CREATE TABLE 会阻止所有操作,因为它会修改 SQL 目录,因此您希望此类操作尽可能短。然后你就可以让 INSERT INTO 在自己的事务中愉快地运行,而不会阻塞任何其他表上的查询(这里不建议对
cloned_table
进行并发更新)。 ==> 这可能不会影响上述情况,但它会让您的数据库同时更好地用于其他查询。
根据您将如何使用
cloned_table
,您可以通过将其放入 UNLOGGED
表 [1] 来完全避免使用日志文件。您可以保留数据,但之后还无法为 UNLOGGED 表启用日志。
您还可以考虑以几个较小的块将数据从
big_table
复制到 cloned_table
。或者甚至使用 MERGE TABLE [1]。