2017-02-01 4 views
1

У меня есть чрезвычайно большая таблица, из которой я хотел бы удалить старые строки. Пример таблицы:Как эффективно удалить истекшие строки из большой таблицы MySQL

| customer_id | first_purchase_date | last_purchase_date | 
|<primary key>|      | <index>   | 

** Я использую эту таблицу примеров для аргументации. Таблица, о которой идет речь, не является таблицей клиентов. За последние 2 месяца реальная таблица выросла до 28 ГБ и используется для расчета чего-то, что требует только 2 недели исторических данных.

Что бы я хотел сделать, это удалить клиентов из этой таблицы, которые в прошлом году ничего не купили. То есть delete from table where last_purchase_date < now() - interval 1 year;

Симпатичное удаление, как это было бы слишком дорогостоящим в базе данных. Я знаю, что раздел можно использовать для усечения старых строк, но я не уверен, как эффективно его реализовать.

Кроме того, если клиент купил что-то, то эта строка может потенциально перейти на другой раздел, обновив last_purchase_date. Не будет ли это дорого?

Заранее благодарю за любое направление!

+0

Вы действительно хотите удалить своих клиентов? –

+1

Partinionning on date - это решение, позволяющее получить лучшие результаты, если производительность вашей проблемы ... но это ваша проблема вообще? А что такое «чрезвычайно большая таблица»?Дайте некоторые цифры. Удаление клиентов редко бывает хорошей идеей, и переместить их в таблицу «архив» было бы лучше. Как вы планируете их удалить? это будет ежегодный процесс (в конце 2017 года, удалить все 2016) или ежедневный процесс (в конце каждого дня удалите те, которые <[дата - 1 год]). Подводя итог, вам действительно нужно добавить дополнительную информацию –

+0

Таблица, о которой идет речь, на самом деле не является базой клиента – AYR

ответ

2

Вы правы, думая, что partitioning это путь вперед, потому что:

Данные, которые теряют свою полезность часто может быть легко удалена из секционированной таблицы, опуская раздел (или разделы), содержащие только это данные. И наоборот, процесс добавления новых данных может в некоторых случаях значительно облегчить добавление одного или нескольких новых разделов для , в котором конкретно хранятся эти данные.

И если это не работает для вас, это еще можно

Кроме того, MySQL 5.7 поддерживает явное выделение разделов для запросов. Например, SELECT * FROM t PARTITION (p0, p1) WHERE c выбирает только те строки в разделах p0 и p1, которые соответствуют условию WHERE . В этом случае MySQL не проверяет другие разделы таблицы t; это может значительно ускорить запросы, когда вы уже знаете раздел , который вы хотите изучить. Выбор раздела также поддерживается для операторов модификации данных DELETE, INSERT, REPLACE, UPDATE и LOAD DATA, LOAD XML.

Поскольку вы хотите удалить материал на основе даты, а не первичный ключ, вам нужна схема разделения RANGE.

Сначала найдите самую старую дату и создавать разделы на основе этого

ALTER TABLE sales 
    PARTITION BY RANGE(TO_DAYS(last_purchase_date)) (
    PARTITION p0 VALUES LESS THAN (TO_DAYS('2018-12-31')), 
    PARTITION p1 VALUES LESS THAN (TO_DAYS('2017-12-31')), 
    PARTITION p2 VALUES LESS THAN (TO_DAYS('2016-12-31')), 
    PARTITION p3 VALUES LESS THAN (TO_DAYS('2015-12-31')), 
    .. 
    PARTITION p10 VALUES LESS THAN MAXVALUE)); 

Выберите нужное количество разделов, но не беспокойтесь слишком много, потому что вы всегда можете изменить разделы позже. Когда вы разделяете, вы даже можете обнаружить, что шаг удаления на самом деле не нужен.

+0

Использование 'PARTITIONING' - отличный способ облегчить удаление старых строк. [_Here_] (https://mariadb.com/kb/en/mariadb/partition-maintenance/) - это мой блог. –

+0

@ e4c5 Спасибо за подробный ответ. Вопрос в том, может ли использование раздела существенно не повлиять на обновление в столбце даты, поскольку ему придется переместить строку в другой раздел. – AYR

+0

Ooops, извините, эта схема не сработает, если дата будет меняться. Это должно быть статично. Можете ли вы опубликовать полную таблицу, чтобы мы могли идентифицировать подходящий столбец – e4c5

Смежные вопросы