簡體   English   中英

有效地插入到 Postgres 中的表中

[英]Efficiently insert into table in Postgres

在我的數據庫中,我將一個樹狀數據結構保存為一個表tab其中包含id (主鍵)、 valuefrom_iddepth ,其中depth (整數)表示到樹根的距離。

現在我想從另一個表candidates (列id, value, from_id )向表tab添加行,但有兩個限制:1)只有新id和 2)只有depth低於某個給定閾值的行(例如 3或 4)。

可能有不止一個from_idtab這一點在新行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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM