问题来源:
MySql 好用,便宜,虽然现在出了很多内存数据库,但是始终不与之存在替代关系,操作方式网上一搜一大堆,但是很可惜,现在互联网早就两只脚踏入大数据时代,很多操作方式已经不适合大数据表。
问题描述:
本文章会持续更新,主要留下作者在工作中遇到大数据表处理的经验
何谓大数据表,官方推荐单表记录数超过600W就必须做分区分表处理,我下面的解决方案,我暂定为已经或者预期超过百万,就必须使用的方式
解决方案:
1. 大数据表迁移(分段提交)
表迁移的方式很多,包括文件迁移等,这里主要介绍通过执行SQL来做分段提交。
建立存储过程,入参 step 代表每多少条记录提交一次,maxIndex_代表最大的ID数
为什么这里不用limit分页?因为limit方式的分页小数据没问题,但是遇到大数据表,随着分页的数量越多,查询越慢,所以推荐使用主键或者索引做分页。
CREATE DEFINER=`root`@`%` PROCEDURE `batch_insert`(in step int,in maxIndex_ int)
BEGIN
DECLARE index_ int default 0;
WHILE index_ < maxIndex_ DO
insert into table_user_new
select * from table_user where id > index_ and id < (index_ + step );
set index_ = index_ + step;
commit;
END WHILE;
END
2. 大数据表加字段
第一步 复制当前表的结构,在新表的基础上新增字段
CREATE TABLE table_user_new LIKE table_user;
alter table table_user_new add name varchar(50) NULL DEFAULT NULL COMMENT '名称';
第二步 采用分段提交方式,进行数据迁移
第三步 把当前表的名字以及创建的新表名字进行更改
RENAME TABLE table_user TO table_user_old,table_user_new TO table_user;
3. 大数据表时间查询
数据小,怎么查都可以,但是遇到大数据,涉及时间字段,只能使用date_sub,只有这样才能走索引
下面附上使用的几个栗子:
-- 今天
select count(1) from table_user where create_time > DATE_SUB(CURRENT_DATE(),INTERVAL 0 day)
-- 昨天
select count(1) from table_user where create_time > DATE_SUB(CURRENT_DATE(),INTERVAL 1 day)
and create_time < DATE_SUB(CURRENT_DATE(),INTERVAL 0 day)
4. 大数据表做分区
对于全新的表做分区,这个网上很多教程,这里不多说
举例工作遇到的场景: 一个生产正在使用的大数据表,由于数据日益递增,分区刻不容缓
解决建议方案如下
- 必须停机
- 重新建立一个复制表结构的分区表
- 和业务沟通,把最近X天需要用到的先迁移过去
- 后续使用JOB或者其他方式,把所有记录做迁移