[英]Efficiently insert into table in Postgres
在我的數據庫中,我將一個樹狀數據結構保存為一個表tab
其中包含id
(主鍵)、 value
、 from_id
和depth
,其中depth
(整數)表示到樹根的距離。
現在我想從另一個表candidates
(列id, value, from_id
)向表tab
添加行,但有兩個限制:1)只有新id
和 2)只有depth
低於某個給定閾值的行(例如 3或 4)。
可能有不止一個from_id
在tab
這一點在新行candidates
。
作為 Postgres 初學者,我希望我的方法是正確的,但效率很低:
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);
我正在尋找加快速度的建議。 與一個事務中的其他兩個操作一起,對於少於 10k 行,這需要幾分鍾。
我從R
工作,使用RPostgres
包,但是我相信這更像是一個 SQL/數據庫問題。
您可以嘗試使用 left join 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);
無論哪種方式,如果tab
有很多行以提高性能,您都可能需要去掉IN
子句。
並且習慣於始終在INSERT
語句中明確寫下目標列,否則如果您對目標表進行更改(例如添加列),語句可能會中斷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.