2010-09-02 102 views
0

我有一個過程,我必須檢查某些指定條目的某個視圖並相應地刪除它們。我爲此使用了以下方法 -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

回答

3

我想你想知道如何刪除每個匹配的項目,如果你的查詢返回很多行。更快,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

2

有什麼我想念使用:

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)