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

问题描述:

我有一个过程,我必须检查某些指定条目的某个视图并相应地删除它们。我为此使用了以下方法 -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 = 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; 

这是有效的方法,还是有更有效的方法来执行此类查询?当然,我正在谈论我选择记录的方式。

+0

@OMG:对不起,是我不好。编辑代码。感谢您指出错误。 – 2010-09-02 05:14:55

我想你想知道如何删除每个匹配的项目,如果你的查询返回很多行。更快,correcter的办法是将运行查询,并遍历它的行:

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; 

http://www.postgresql.org/docs/8.4/static/plpgsql-control-structures.html#PLPGSQL-RECORDS-ITERATING

一个更好的方法可能是,如果可以简单地使用DELETE FROM x WHERE ...声明。这取决于删除的简单程度。

+0

优雅的答案,+1。但是,我自己决定选择这一个作为可接受的答案,看看是否可以找到其他方法。谢谢。 – 2010-09-02 05:10:59

+1

当单个SQL语句执行相同的工作时使用循环几乎总是错误的选择。数据库并不是要逐行处理数据,而是要处理数据集。去单DELETE语句,你的表现会好很多 – 2010-09-04 22:00:19

+0

我全心全意地同意,这就是为什么我把最后一行放在那里。但是从这个问题来看,并不是100%显而易见的,一个SQL语句*会做同样的工作;无论如何,如果提问者对DB非常陌生,以至于他们不熟悉DELETE ... WHERE(复杂查询)技巧,我认为逐渐地将它们移向它是没有害处的。 – Edmund 2010-09-04 23:00:26

有什么我想念使用:

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)