在数据库中,我将类似树的数据结构保存为表tab
,其中包含列id
(主键),value
,from_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 /数据库问题。
答案 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
语句中显式写下目标列,因为如果对目标表进行更改(例如,添加一列。