如何有效地从大型MySQL表中删除过期的行

时间:2017-02-01 15:37:20

标签: mysql sql partitioning delete-row

我有一个非常大的表,我想从中删除旧行。表格示例:

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

**我正在使用这个示例表作为参数的缘故。有问题的表不是客户表。实际表格在过去2个月内已经增长到28 GB,用于计算仅需要2周历史数据的内容。

我想要做的是删除此表中过去一年没有购买任何东西的客户。即delete from table where last_purchase_date < now() - interval 1 year;

如此简单的删除对数据库来说太昂贵了。我知道可以使用分区来截断旧行,但我不确定如何有效地实现它。

此外,如果客户购买了某些东西,那么通过更新last_purchase_date,该行可能会移动到不同的分区。这也不贵吗?

提前感谢您的任何指示!

1 个答案:

答案 0 :(得分:2)

你认为fiddle是前进之路是正确的,因为:

  

失去其实用性的数据通常可以很容易地从a中删除   通过删除包含的分区(或分区)来分区表   只有那些数据。相反,在某些方面可以添加新数据的过程   通过添加一个或多个新分区可以极大地促进这些情况   专门存储该数据。

如果这对你不起作用,那么它仍然可以

  

此外,MySQL 5.7支持显式分区选择   查询。例如,SELECT * FROM t PARTITION(p0,p1)WHERE c&lt;五   仅选择与WHERE匹配的分区p0和p1中的那些行   条件。在这种情况下,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));

选择适当数量的分区但不要过于担心,因为您以后可以随时更改分区。在进行分区时,您甚至可能会发现删除步骤毕竟不是必需的。