Лучший способ удалить 5К строк из таблицы Innodb с 30M строк - PullRequest
2 голосов
/ 02 декабря 2010

таблица:

  • foreign_id_1
  • foreign_id_2
  • целое число
  • date1
  • date2
  • основной (Foreign_id_1, Foreign_id_2)

Запрос: delete from table where (foreign_id_1 = ? or foreign_id_2 = ?) and date2 < ?

Без даты запрос занимает около 40 сек. Это слишком высоко :( С датой намного дольше ..

Варианты:

  • create другой стол и insert select, затем rename
  • использовать лимит и запускать запрос несколько раз
  • разделенный запрос для запуска foreign_id_1 затем foreign_id_2
  • использовать выбор, затем удалить по одной строке

Есть ли более быстрый способ?


mysql> explain select * from compatibility where user_id = 193 or person_id = 193 \G
           id: 1
  select_type: SIMPLE
        table: compatibility
         type: index_merge
possible_keys: PRIMARY,compatibility_person_id_user_id
          key: PRIMARY,compatibility_person_id_user_id
      key_len: 4,4
          ref: NULL
         rows: 2
        Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where
1 row in set (0.00 sec)

mysql> explain select * from compatibility where (user_id = 193 or person_id = 193) and updated_at < '2010-12-02 22:55:33' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: compatibility
         type: index_merge
possible_keys: PRIMARY,compatibility_person_id_user_id
          key: PRIMARY,compatibility_person_id_user_id
      key_len: 4,4
          ref: NULL
         rows: 2
        Extra: Using union(PRIMARY,compatibility_person_id_user_id); Using where
1 row in set (0.00 sec)

Ответы [ 2 ]

2 голосов
/ 03 декабря 2010

Наличие OR в вашем WHERE делает MySQL неохотно (если не полностью отказывается) использовать индексы в ваших полях user_id и / или person_id (если есть - отображение CREATE TABLE будетуказать, если был).

Если вы можете добавить индексы (или изменить существующие, так как я имею в виду составные индексы), я, вероятно, добавлю два:

ALTER TABLE compatibility 
ADD INDEX user_id_updated_at (user_id, updated_at),
ADD INDEX persona_id_updated_at (person_id, updated_at);

Соответственно, при условии, что строки равны DELETE не должно быть удалено атомарно (т.е. происходит в одно и то же время).

DELETE FROM compatibility WHERE user_id = 193 AND updated_at < '2010-12-02 22:55:33';

DELETE FROM compatibility WHERE person_id = 193 AND updated_at < '2010-12-02 22:55:33';
0 голосов
/ 04 декабря 2010

К настоящему времени объем данных составляет 40 млн. (+ 33%) и быстро растет.Поэтому я начал искать другое, не-sql, решение.

Спасибо.

...