Я ищу, чтобы найти эффективный способ удаления дублированных записей из моей базы данных. Во-первых, я использовал хранимую процедуру, которая использует объединения и т. Д., Что заставило запрос выполнить очень медленно. Теперь я пытаюсь использовать другой подход. Пожалуйста, обратите внимание на следующие вопросы:Эффективный способ удаления повторяющихся строк из миллионов записей
/* QUERY A */
SELECT *
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
Этот запрос просто выполняется в течение 12 секунд, с результатом 182.400 записей. Количество строк в таблице в настоящее время 420.930.407, а col1 и col3 индексируются.
Следующий запрос:
/* QUERY B */
WITH ALL_RECORDS AS
(SELECT id
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value)
SELECT *
FROM ALL_RECORDS
Этот запрос занял менее 2 секунд, и дает мне все корочки 182.400 записей в таблице (в соответствии с пунктом где).
Тогда мой последний запрос, запрос, который выбирает самый низкий (первый) идентификатор всех записей, сгруппированных по столбцам, которые я хочу, чтобы группа на проверки дубликатов:
/* QUERY C */
SELECT MIN(id)
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6
Опять же, этот запрос выполняется менее чем за 2 секунды. Результат - 30.400, что означает, что есть уникальные записи из 30.400 уникальных записей из 182.400 записей.
Теперь, я хотел бы удалить (или, сначала выберите, чтобы убедиться, что у меня есть правильный запрос) все записи, которые не уникальны. Итак, я хотел бы удалить 182.400 - 30.400 = 152.000 записей из my_table.
Я думал, что объединить два последних запроса: получить все идентификаторы, принадлежащие моему набору данных, в соответствии с предложением where в col1, col2 и col3 (запрос B), а затем удалить/выбрать все записи из этого набора данных который id не находится в списке идентификаторов уникальной записи (запрос C).
Однако, когда я выбираю все из запроса B, где запрос B.id NOT IN query C, запрос не принимает 2, 4 или 12 (14 или 16) секунд, но, кажется, берется навсегда (20 000 записей, показанных после 1 минута, около 40.000 через 2 минуты, поэтому я отменил запрос, так как он найдет 152 000 записей, что займет 8 минут таким образом).
WITH ALL_RECORDS AS
(SELECT id
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value)
SELECT id
FROM ALL_RECORDS
WHERE id NOT IN
(SELECT MIN(id)
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6)
Я знаю NOT IN
медленно, но я не могу понять, как именно это медленно (так как запросы без кнопки не частично выполнить менее чем за 2 секунды каждый).
Есть ли у кого-нибудь хороший совет для меня, как решить эту загадку?
------------------ Дополнительная информация ------------------
Предыдущее решение было следующий хранимая процедура. По какой-то причине он отлично работает в моей среде принятия, но не в моей производственной среде. В настоящее время у нас более 400 миллионов записей о производстве и чуть более 2 миллионов записей о принятии, поэтому это может быть причиной.
DELETE my_table
FROM my_table
LEFT OUTER JOIN
(SELECT MIN(id) AS RowId,
col1,
col2,
col3,
col4,
col5,
col6
FROM my_table
WHERE col1 = value
AND col2 = value
AND col3 = value
GROUP BY col1,
col2,
col3,
col4,
col5,
col6) AS KeepRows ON my_table.id = KeepRows.RowId
WHERE KeepRows.RowId IS NULL
AND my_table.col1 = value
AND my_table.col2 = value
AND my_table.col3 = value
Я основывал это решение на другой ответ на StackOverflow (не может найти его в данный момент), но я чувствую, что я должен быть в состоянии создать запрос, основанный на Query B и C, который выполняется в течение нескольких секунды ...
Это, кажется, работает очень быстро, спасибо! Я постараюсь реализовать его завтра, и, надеюсь, он будет работать и на производстве :) – Tjab