Что заставило бы эту вставку SQL работать очень медленно?
Я использую подзапрос, чтобы найти дубликаты строк в системе.
SELECT * FROM locations l2 WHERE l2.id IN (
SELECT min(l1.id) FROM locations l1
GROUP BY l1.address, l1.city, l1.industry_id
HAVING count(*) > 1
)
Этот запрос выполняется довольно быстро, около 0,4 с. Однако, если я попытаюсь обернуть вставку вокруг него:
INSERT INTO duplicate_locations (
SELECT * FROM locations l2 WHERE l2.id IN (
SELECT min(l1.id) FROM locations l1
GROUP BY l1.address, l1.city, l1.industry_id
HAVING count(*) > 1
)
)
Этот запрос занял 6 минут для 100 строк.
Все остальное в системе работает нормально. Таблицы имеют одинаковую структуру, MyISAM, MariaDB 5.5 (без EXPLAIN INSERT). Сначала я подумал, что это проблема с таблицей, но я попробовал новую таблицу и получил аналогичный результат, поэтому в запросе должна быть проблема. Диски в порядке, это все загрузка процессора во время работы. Мне удалось скопировать всю таблицу местоположений в считанные секунды (десятки тысяч строк).
1 ответ
Подзапросы в предложениях MySQL WHERE, как правило, снижают производительность, и их следует избегать во всех случаях, кроме простейших случаев или в ситуациях, когда их использование не приводит к безумно сложному запросу. Попробуйте вместо этого:
INSERT INTO duplicate_locations
SELECT l0.* FROM locations AS l0
INNER JOIN (
SELECT min(id) AS firstID
FROM locations
GROUP BY address, city, industry_id
HAVING count(*) > 1
) AS firstL
ON l0.id = firstL.firstID
;