有效地插入Postgres中的表

时间:2019-12-01 23:11:43

标签: sql r postgresql

在数据库中,我将类似树的数据结构保存为表tab,其中包含列id(主键),valuefrom_id和{{1 }},其中depth(整数)表示距树根的距离。

现在,我想从另一个表depth(列tab)向表candidates添加行,但有两个限制:1)仅新建id, value, from_id和2)仅id低于给定阈值(例如3或4)的行。

depth中可能有多个from_id指向tab中的新行。

作为Postgres初学者,我希望我的方法是正确的,但是效率很低:

candidates

我正在寻找加快速度的建议。连同一个事务中的其他两个操作,这需要几分钟才能完成不到1万行的操作。

我正在使用insert into tab select distinct c.id, c.value, c.from_id, t.depth+1 as depth from candidates as c join tab as t on t.id=c.from_id where depth<3 and c.id not in (select id from tab); 软件包在R进行工作,但是我认为这更多是SQL /数据库问题。

1 个答案:

答案 0 :(得分:1)

如果尝试加入tab并检查其id是否为NULL,您可以尝试。

INSERT INTO tab
            (id,
             value,
             from_id,
             depth)
SELECT c1.id,
       c1.value,
       c1.from_id,
       t1.depth + 1
       FROM candidates c1
            INNER JOIN tab t1
                       ON t1.id = c1.from_key
            LEFT JOIN tab t2
                      ON t2.id = c1.id
       WHERE t1.depth + 1 < 3
             AND t2.id IS NULL;

与此同时,尝试将索引放在tab (id, depth)candidates (from_key)上。

另一个选项是带有NOT EXISTS的相关子查询。

INSERT INTO tab
            (id,
             value,
             from_id,
             depth)
SELECT c1.id,
       c1.value,
       c1.from_id,
       t1.depth + 1
       FROM candidates c1
            INNER JOIN tab t1
                       ON t1.id = c1.from_key
       WHERE t1.depth + 1 < 3
             AND NOT EXISTS (SELECT *
                                    FROM tab t2
                                    WHERE t2.id = c1.id);

如果IN有很多行来提高性能,则可能需要用两种方法摆脱tab子句。

并习惯于始终在INSERT语句中显式写下目标列,因为如果对目标表进行更改(例如,添加一列。