Postgresql: как сделать следующий запрос более эффективным - PullRequest
0 голосов
/ 02 сентября 2010

У меня есть процедура, где я должен проверить определенный вид для некоторых указанных записей и соответственно удалить их.Для этой цели я использовал следующий подход:

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;

Это эффективный способ или существует более эффективный способ выполнения этого типа запроса?Разумеется, я говорю о том, как я выбираю записи.

Ответы [ 2 ]

3 голосов
/ 02 сентября 2010

Я думаю, вам интересно, как вы можете удалить каждый соответствующий элемент, если ваш запрос возвращает много строк. Более быстрый и корректный способ - выполнить запрос один раз и выполнить цикл по его строкам:

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 ..., если это возможно. Это зависит от того, насколько просто удаление.

2 голосов
/ 02 сентября 2010

Есть что-то, по чему я скучаю:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...