将运行中的大表修改为分区表

本文章代码仅限于以数据时间按月水平分区,其他需求可自行修改代码实现

1. 创建一张分区表

这张表的表字段和原表的字段一摸一样,附带分区

1

2

3

4

5

6

7

8

9

10

11

12

CREATE TABLE `metric_data_tmp`  (

    id bigint primary key auto_increment,

    metric varchar(128),

    datadt datetime not null unqine,

    value decimal(30, 6)

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8

partition by range (to_days(DATADT)) (

    PARTITION p201811 VALUES LESS THAN (to_days("2018-12-01")),

    PARTITION p201812 VALUES LESS THAN (to_days("2019-01-01")),

    PARTITION p201901 VALUES LESS THAN (to_days("2019-02-01")),

    PARTITION p201902 VALUES LESS THAN (to_days("2019-03-01")),

);

2. 将原表数据复制到临时表

  • 直接通过insert语句

1

insert into metric_data_tmp select * from metric_data;

  • 数据量非常大,可使用select into outfile, Load data file方式导出导入

1

2

SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM metric_data;

LOAD DATA INFILE 'data.txt' INTO TABLE metric_data_tmp FIELDS TERMINATED BY ',';

3. 重命名分区表和历史表:

1

2

rename table metric_data to metric_data_bak;

rename table metric_data_tmp to metric_data;

4. 通过数据库的定时任务定时自动创建下月的分区

  • 存储过程

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

delimiter $$

use `db_orbit`$$

drop procedure if exists `create_partition_by_month`$$

create procedure `create_partition_by_month`(in_schemaname varchar(64), in_tablename varchar(64))

begin

    # 用于判断需要创建的表分区是否已经存在

    declare rows_cnt int unsigned;

    # 要创建表分区的时间

    declare target_date timestamp;

    #分区的名称,格式为p201811

    declare partition_name varchar(8);

        

    #要创建的分区时间为下个月

    set target_date = date_add(now(), interval 1 month);

    set partition_name = date_format( target_date, 'p%Y%m' );

        

    # 判断要创建的分区是否存在

    select count(1) into rows_cnt from information_schema.partitions t where table_schema = in_schemaname and table_name = in_tablename and ifnull(t.partition_name, '') = partition_name;

    if rows_cnt = 0 then

        set @sql = concat(

            'alter table `',

            in_schemaname,

            '`.`',

            in_tablename,

            '`',

            ' add partition (partition ',

            partition_name,

            " values less than (to_days('",

            date_format(DATE_ADD(target_date, INTERVAL 1 month), '%Y-%m-01'),

            "')) engine = innodb);"

        );

        prepare stmt from @sql;

        execute stmt;

        deallocate prepare stmt;

     else

       select concat("partition `", partition_name, "` for table `",in_schemaname, ".", in_tablename, "` already exists") as result;

     end if;

end$$

delimiter ;

  • 创建定时任务,定时执行存储过程创建分区

1

2

3

4

5

6

7

8

9

10

11

12

13

14

DELIMITER $$

#该表所在的数据库名称

USE `db_orbit`$$

CREATE EVENT IF NOT EXISTS `generate_partition_for_metric_data`

ON SCHEDULE EVERY 1 MONTH   #执行周期,还有天、月等等

STARTS '2019-03-15 00:00:00'

ON COMPLETION PRESERVE

ENABLE

COMMENT 'Creating partitions'

DO BEGIN

    #调用刚才创建的存储过程,第一个参数是数据库名称,第二个参数是表名称

    CALL db_orbit.create_partition_by_month('db_orbit', 'metric_data');

END$$

DELIMITER ;

5.其他

  • 查看表分区情况的SQL

1

2

3

4

5

6

select

    partition_name part, 

    partition_expression expr,

    partition_description descr,

    table_rows 

from information_schema.partitions where table_name='metric_data';

MySQL大数据表水平分区优化的详细步骤的更多相关文章

  1. MySQL大数据量分页性能优化

    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...

  2. Mysql大数据表优化处理

    原文链接: https://segmentfault.com/a/1190000006158186 当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表 ...

  3. mysql大数据表优化

    1.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描. 2.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉 ...

  4. 制作mysql大数据表验证覆盖索引

    昨天跟同事聊起数据表性能的问题,能不能仅用覆盖索引实现数据的汇总统计.找了一个开发环境已有的数据表进行测试,通过explain命令,能看到mysql通过覆盖索引就能实现sum的需求,而无须去读取实际行 ...

  5. 【MYSQL】mysql大数据量分页性能优化

    转载地址: http://www.cnblogs.com/lpfuture/p/5772055.html https://www.cnblogs.com/shiwenhu/p/5757250.html ...

  6. mysql大数据表删除操作锁表,导致其他线程等待锁超时(Lock wait timeout exceeded; try restarting transaction;)

    背景: 1.有一个定时任务,每10分钟入一批统计数据: 2.另一个定时任务,每天定时清理7天前数据,此定时任务每天01:18:00执行: 现象: 每天01:20:00的统计数据入库失败,异常信息如下, ...

  7. mysql大数据表改表结构方案

    有一个表有上千W数据, 用什么方法给这个表加一个字段最快?1. alert2. 建一个表和第一个表一样,只是多了要加的字段,然后用多个INSERT INTO SELECT语句limit写入3. 就是导 ...

  8. mysql大数据量之limit优化

    背景:当数据库里面的数据达到几百万条上千万条的时候,如果要分页的时候(不过一般分页不会有这么多),如果业务要求这么做那我们需要如何解决呢?我用的本地一个自己生产的一张表有五百多万的表,来进行测试,表名 ...

  9. MySQL大数据分页的优化思路和索引延迟关联

    之前上次在部门的分享会上,听了关于MySQL大数据的分页,即怎样使用limit offset,N来进行大数据的分页,现在做一个记录: 首先我们知道,limit offset,N的时候,MySQL的查询 ...

随机推荐

  1. docker内存和cpu调试

    本地启动了一个sshd的容器服务,但该容器经常会被重启导致ssh连接失败,使用kubectl describe pod命令查看改命令发现有容器返回值为137,一般是系统环境原因,且一般为内存不足导致的 ...

  2. Linux安装go语言开发包

    1.下载go语言安装包,eg:go1.7.1.linux-amd64.tar.gz2.安装go语言 $ cd /home/xm6f/dev $ tar -zxvf go1.7.1.linux-amd6 ...

  3. CentOS7 下编译安装 Samba,什么是 SMB/CIFS 协议

    目录 一.关于 Samba 1. SMB 2. Samba 二.yum 安装 Samba 1. 安装 Samba 2. 查看版本 3. 查看配置文件 4. 启动服务 5. 本地客户端验证 6. Win ...

  4. Mybatis在非spring环境下配置文件中使用外部数据源(druidDatasource)

    Spring环境下, MyBatis可以通过其本身的增强mybatis-spring提供的org.mybatis.spring.SqlSessionFactoryBean来注入第三方DataSourc ...

  5. SpringBoot入门 (七) Redis访问操作

    本文记录学习在SpringBoot中使用Redis. 一 什么是Redis Redis 是一个速度非常快的非关系数据库(Non-Relational Database),它可以存储键(Key)与 多种 ...

  6. Eclipse 处理 Console 打印信息自动删除

    开发中,特识是需要项目运行打印日志很长的时候需要查看打印的日志, Eclipse没经过设定的话,会自动80000行之前的日志记录. 想要日志一直打印下去处理方法: Preferences --> ...

  7. Solr 配置中文分词器 IK

    1. 下载或者编译 IK 分词器的 jar 包文件,然后放入 ...\apache-tomcat-8.5.16\webapps\solr\WEB-INF\lib\ 这个 lib 文件目录下: IK 分 ...

  8. C#操作MongoDB入门

    1.MongoDB安装及配置 (1)下载:   mongodb官网 https://www.mongodb.com/download-center      进入官网下载页,你会发现版本都是windo ...

  9. Redis哨兵(sentinel)模式搭建

    一.Sentinel介绍 之前骚了一波Redis的简介及应用场景,今天试了下他的哨兵模式: Sentinel是Redis的高可用性(HA)解决方案,由一个或多个Sentinel实例组成的Sentine ...

  10. git 撤销add和commit

    有时候改完代码发现改错分支了,而这个时候已经add或者commit了,怎么办,有办法: 1.若果已经add .  了这个时候可以使用git stash命令,具体操作命令如下: (1) > git ...