Что заставило бы эту вставку 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
;
Другие вопросы по тегам