關于什么是分區和分表,可以先參考下面前兩篇文章。
MySQL 分庫分表與分區的區別和思考
搞懂MySQL分區
MySQL分區表的真正作用
分區原理和優缺點
分區是同一表中不同行的記錄分配到不同的物理文件中
我們具體是否要使用分區,需要考慮幾點
- 什么場景使用分區
- 分區是基于mysql底層的實現,不影響業務。分表可以支持數據量大的表進行分拆,但是需要我們在業務端進行支持
- 我們現在有個表,目前的數據量在2億+,隨著業務的發展,每天新增的數據至少在500W+
- 首先單機的性能和容量足夠,完全基于內網的訪問,沒有太大的讀并發,但是需要保證單語句查詢的速度
- 每天的新增數據太大,我么先考慮按天來進行分區,分區后的所有區隔離,我們場景也不需要經常的跨天訪問
- 分區后性能效果如何,能否解決問題
- 我們首先使用部分數據測試,測試表1900W+數據,加入分區
select *
from table
where s.start_time BETWEEN "2019-10-18 00:00:01" and "2019-10-18 23:59:59"
我們按照天來分區,一天的數據25W左右
-
分區前
image.png -
分區后
image.png
初步查看,效果明顯。
問題?
- 在插入數據的時候,缺少對應的分區會插入失敗
- 可以設置maxValue進行容錯(也就是可以接收所有數據的分區),避免異常的數據操作
- 分區后如何恢復?
- 分區后的數據分到了不同的物理文件,不同分區數據和索引都是獨立的,刪除分區就會刪除對應的數據。
- 想恢復不分區,可以考慮創建結構相同的表遷移數據
- 分區后的跨區查詢速度如何?
接下來 - 新插入分區的值上限,需要比目前的大,所以得考慮后續數據量的增長問題,合理的設置分區值
分區操作語句
查看分區情況
select
partition_name part,
partition_expression expr,
partition_description descr,
table_rows
from information_schema.partitions where
table_schema = schema()
and table_name='stb_traffic_info_lane';
添加分區
ALTER table stb_traffic_info_lane
add partition (partition p20200726 VALUES LESS THAN (737995) ENGINE = InnoDB);
刪除分區
alter table stb_traffic_info_lane drop partition p20200726;
創建表,增加分區。數據從現有的表拷貝過來
CREATE TABLE `stb_traffic_info_lane_2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`start_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`end_time` datetime DEFAULT NULL,
`remarks` varchar(12800) DEFAULT NULL,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
PRIMARY KEY (`id`,`start_time`),
KEY `index_1` (`index_id`,`time_type`,`start_time`,`end_time`,`cross_id`,`branch_id`,`lane_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
PARTITION BY RANGE (TO_DAYS(start_time))
PARTITIONS 2(
PARTITION p20191018 VALUES LESS THAN (TO_DAYS('20191018')) ENGINE = INNODB,
PARTITION p20191019 VALUES LESS THAN (TO_DAYS('20191019')) ENGINE = INNODB
)
從其他表遷移數據
insert into `stb_traffic_info_lane_2`
select * from `stb_traffic_info_lane_1`