Postgresql:如何提高以下查询的效率

Postgresql:如何提高以下查询的效率,sql,postgresql,Sql,Postgresql,我有一个过程,在这个过程中,我必须检查某个视图中的某些指定条目,并相应地删除它们。为此,我采用了以下方法: SELECT id_1, id_2, id_3, id_4 INTO v_id_1, v_id_2, v_id_3, v_id_4 FROM v_doc WHERE parent_id_1 =

我有一个过程,在这个过程中,我必须检查某个视图中的某些指定条目,并相应地删除它们。为此,我采用了以下方法:

SELECT      id_1,
            id_2, 
            id_3, 
            id_4
INTO        v_id_1,
            v_id_2, 
            v_id_3,
            v_id_4
FROM        v_doc
WHERE       parent_id_1 = p_id_1    -- 'p_' suffix stands for function parameters
            AND parent_id_2 = p_id_2
            AND parent_id_3 = p_id_3
LIMIT       1
;

WHILE v_id_1 IS NOT NULL
LOOP
    -- Code for child document line deletion goes here


    SELECT      id_1,
                id_2, 
                id_3, 
                id_4
    INTO        v_id_1,
                v_id_2, 
                v_id_3,
                v_id_4
    FROM        v_doc
    WHERE       parent_id_1 = p_id_1
                AND parent_id_2 = p_id_2
                AND parent_id_3 = p_id_3
    LIMIT       1
    ;
END LOOP;

这是一种有效的方法,还是有一种更有效的方法来执行这种类型的查询?当然,我说的是我选择记录的方式。

我想您想知道,如果查询返回许多行,如何删除每个匹配项。一种更快、更正确的方法是运行查询一次,并循环查询行:

DECLARE
    r RECORD;
BEGIN
    FOR r IN SELECT id_1, id_2, id_3, id_4 
               FROM v_doc 
              WHERE id_1 = p_id_1 
                AND id_2 = p_id_2 
                AND id_3 = p_id_3 LOOP
        -- delete item for r.id_1, r.id_2, etc.
    END LOOP;
END;


如果可能的话,更好的方法可能是简单地使用
deletefromx WHERE…
语句。这取决于删除有多简单。

如果查询返回多行,您可能想知道如何删除每个匹配项。一种更快、更正确的方法是运行查询一次,并循环查询行:

DECLARE
    r RECORD;
BEGIN
    FOR r IN SELECT id_1, id_2, id_3, id_4 
               FROM v_doc 
              WHERE id_1 = p_id_1 
                AND id_2 = p_id_2 
                AND id_3 = p_id_3 LOOP
        -- delete item for r.id_1, r.id_2, etc.
    END LOOP;
END;


如果可能的话,更好的方法可能是简单地使用
deletefromx WHERE…
语句。这取决于删除有多简单。

我是否错过了使用:

DELETE FROM v_doc
 WHERE EXISTS(SELECT NULL
                FROM v_doc x
               WHERE x.id_1 = v_doc.id_1
                 AND x.id_2 = v_doc.id_2
                 AND x.id_3 = v_doc.id_3
                 AND x.id_4 = v_doc.id_4
                 AND x.parent_id_1 = p_id_1
                 AND x.parent_id_2 = p_id_2
                 AND x.parent_id_3 = p_id_3)

我是否错过了以下使用方法:

DELETE FROM v_doc
 WHERE EXISTS(SELECT NULL
                FROM v_doc x
               WHERE x.id_1 = v_doc.id_1
                 AND x.id_2 = v_doc.id_2
                 AND x.id_3 = v_doc.id_3
                 AND x.id_4 = v_doc.id_4
                 AND x.parent_id_1 = p_id_1
                 AND x.parent_id_2 = p_id_2
                 AND x.parent_id_3 = p_id_3)

优雅的回答,+1。然而,我坚持不选择这一个作为公认的答案,看看是否还有其他方法可以找到。谢谢。当一条SQL语句执行相同的任务时,使用循环几乎总是错误的选择。数据库不是用来逐行处理数据,而是用来处理数据集。我完全同意这一点,这就是为什么我把最后一行放在那里的原因。但是,从这个问题上看,一条SQL语句可以完成同样的工作,这并不是100%明显的;在任何情况下,如果询问者对DBs如此陌生以至于他们不熟悉
DELETE。。。WHERE(复杂查询)
诀窍,我认为让他们逐渐接近它并没有坏处。优雅的回答,+1。然而,我坚持不选择这一个作为公认的答案,看看是否还有其他方法可以找到。谢谢。当一条SQL语句执行相同的任务时,使用循环几乎总是错误的选择。数据库不是用来逐行处理数据,而是用来处理数据集。我完全同意这一点,这就是为什么我把最后一行放在那里的原因。但是,从这个问题上看,一条SQL语句可以完成同样的工作,这并不是100%明显的;在任何情况下,如果询问者对DBs如此陌生以至于他们不熟悉
DELETE。。。WHERE(复杂查询)
诀窍,我看不出让他们逐渐接近它有什么害处。@OMG:对不起,我的错。编辑代码。谢谢你指出错误。@OMG:对不起,我的错。编辑代码。谢谢你指出错误。