2015-01-03 3 views
0

Я использую следующий запрос для удаления нескольких записей, кроме одного из моей таблицы. Он хорошо работает с маленькими столами, но он застрял, когда я попробовал его с таблицей, содержащей> 130000 записей. Дело в том, что я даже не ошибаюсь. PhpMyAdmin просто застревает и запрос ("загрузка ... желтая линия), в основном принимает навсегдаУдаление нескольких записей из очень большой таблицы (запрос берется навсегда)

Моей структуры таблицы

person_id (AI & PK) 
person_name (I want to delete multiple person_name records except one) 

запроса

DELETE t2 
FROM `person` t1 
INNER JOIN `person` t2 
    ON t1.person_name = t2.person_name 
    AND t1.person_id < t2.person_id; 

UPDATE:. Я не имею указатель на стол человека. Но мои три другие таблицы (person_job & person_image, book_who_wrote_it) содержат внешние ключи из таблицы лиц (person_id)

ответ

4

Во-первых, вы имеют индекс на person(person_name, person_id)? Это будет место для начала.

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

create temporary table tmp_person as 
    select p.* 
    from person p join 
     (select person_name, max(person_id) as max_person_id 
      from person 
     ) pp 
     on p.person_id = pp.max_person_id; 

truncate table person; 

insert into person 
    select * from tmp_person; 

Убедитесь, что вы проверить tmp_personперед тем усечения person! Truncate не регистрирует удаление каждой строки, поэтому в большинстве случаев она намного, намного, намного быстрее, чем delete.

Примечание:

Если вы действительно только две колонки в person, то вы можете упростить первый запрос к:

create temporary table tmp_person as 
    select person_name, max(person_id) as max_person_id 
    from person; 
+0

Нет, я не иметь индекс для таблицы людей. Но мои три другие таблицы (person_job & person_image, book_who_wrote_it) содержат внешние ключи из таблицы person (person_id). – salep

+0

@salep. , , Индекс поможет вашему запросу. –

+0

Из OP очевидно, что он хочет максимального значения 'person_id' (я мог ошибаться - или, может быть, это не имеет значения?) –

0

попробовать это

 DELETE 
     FROM `person` t1 
     where person_id not in 
        (select * from 
         (select person_id from person group by person_name)x) 
Смежные вопросы