1. MySQL大表优化方案选型:分区表与分表的本质区别
最近在优化公司订单系统时,遇到了单表数据量过亿导致的查询性能问题。和团队讨论方案时,一位资深架构师提到:"单表delete数据后,空间不会真正释放"。这句话引发了我对MySQL存储机制的深入探究,也让我重新审视分区表和分表这两种常用方案的底层差异。
1.1 分区表的实现原理
分区表本质上是一个逻辑上的虚拟表,由多个物理子表组成。当我们创建如下的按月分区订单表时:
sql复制CREATE TABLE tb_order (
order_id INT AUTO_INCREMENT,
order_amount DECIMAL(19,4),
order_date DATE,
PRIMARY KEY (order_id, order_date)
) PARTITION BY RANGE(TO_DAYS(order_date))(
PARTITION p0 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p1 VALUES LESS THAN (TO_DAYS('2023-03-01')),
PARTITION p2 VALUES LESS THAN (TO_DAYS('2023-04-01')),
PARTITION p3 VALUES LESS THAN (TO_DAYS('2023-05-01')),
PARTITION pMAX VALUES LESS THAN MAXVALUE
);
MySQL会在磁盘上为每个分区创建独立的.ibd文件。这种设计带来几个关键特性:
- 透明分区访问:应用层看到的仍是单表,分区细节对业务代码透明
- 局部索引:每个分区维护自己的索引,没有全局索引概念
- 并行查询:不同分区可并行扫描(需满足条件)
重要提示:分区表的所有分区必须使用相同存储引擎,这是与分表方案的本质区别之一。我曾踩过一个坑:尝试将历史分区改为ARCHIVE引擎以节省空间,结果导致整个表不可用。
1.2 分表的实现方式
分表则是完全手动创建多个结构相同的物理表,如tb_order_1到tb_order_4。
