Запрос DELETE выполняется слишком долго - PullRequest
0 голосов
/ 05 декабря 2011

Я знаю, что это может быть избыточно, но у меня один и тот же запрос выполнялся в течение почти 3 дней, и прежде чем убить его, я хотел бы получить проверку исправности сообщества.

DELETE
FROM    mytble
WHERE   ogc_fid NOT IN
    (SELECT     MAX(dup.ogc_fid)
        FROM        mytble As dup
        GROUP BY    dup.id)

mytble isимя таблицы, ogc_fid - это имя поля уникального идентификатора, а id - это имя поля, которое я хочу, чтобы был уникальным идентификатором.В таблице 41 миллион записей, и индексы созданы, и все, поэтому я все еще немного обеспокоен тем, почему его завершение занимает так много времени.Есть мысли по этому поводу?

Ответы [ 2 ]

1 голос
/ 05 декабря 2011

Если я правильно понял, вы хотите удалить все записи, для которых запись с одинаковым dup_id (но с более высоким ogc_fid) существует. И оставляйте только те, у кого самый высокий ogc_fid.

-- DELETE -- uncomment this line and comment the next line if proven innocent.
SELECT COUNT(*)
  FROM   mytble mt
 WHERE   EXISTS (
  SELECT *
    FROM mytble nx
   WHERE nx.dup_id = mt.dup_id    -- there exists a row with the same dup_id
     AND nx.ogc_fid > mt.ogc_fid  -- , ... but with a higher ogc_fid 
);

С индексом для dup_id (и, возможно, для ogc_id) это должно работать, может быть, несколько минут для записей 41M.

ОБНОВЛЕНИЕ: если индексов не существует, вы могли бы ускорить вышеуказанные запросы, сначала создав индекс:

 CREATE UNIQUE INDEX sinterklaas ON mytble (dup_id, ogc_id);
1 голос
/ 05 декабря 2011

Было бы неплохо, если бы вы предоставили explain вывод, но то, что вы делаете , может быть быстрее, если вы сделаете вот так (опять же, я посмотрю explain):

DELETE FROM mytable d
USING mytable m
 LEFT JOIN (SELECT max(ogc_fid) AS f FROM mytble GROUP BY id) AS q ON m.ogc_fid=q.f
WHERE d.ogc_fid=m.ogc_fid AND q.f IS NULL;
...