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

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

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. JavaScrip t对象和 JSON 数据格式转换

    <script> //定义一个js对象 var person = { firstName: "John", lastName: "Doe", age ...

  2. 复刻smartbits的国产网络测试工具minismb-如何添加数据流

    复刻smartbits的国产网络性能测试工具minismb,是一款专门用于测试智能路由器,网络交换机的性能和稳定性的软硬件相结合的工具.可以通过此工具测试任何ip网络设备的端口吞吐率,带宽,并发连接数 ...

  3. Elasticsearch java客户端调用cat服务

    开发环境,测试环境,预发环境和生产环境一般相互隔离的,使用开发环境或者测试环境可以使用cat来查看索引的情况 例如: 但预防环境和测试环境是不允许访问的,那怎么办呢? 可以使用后台来查看上述信息,提供 ...

  4. study design of ADNI

    AD(Alzheimer’s disease):不可逆的神经退化,患病人员会由于脑部问题的恶化而导致心智功能不健全. ADNI:阿尔茨海默氏症神经成像项目 ADNI的总体目标是验证用于阿尔茨海默病临床 ...

  5. 【LeetCode题解】24_两两交换链表中的节点(Swap-Nodes-in-Pairs)

    目录 描述 解法一:迭代 思路 Java 实现 Python 实现 复杂度分析 解法二:递归(不满足空间复杂度要求) 思路 Java 实现 Python 实现 复杂度分析 更多 LeetCode 题解 ...

  6. python学习之内存机制

    不可变对象(字符串.元组) 1. a = 1 首先在内存中创建对象1,并记录对象的引用计数为1次. id(a) 查看变量a引用的对象的内存地址 2. b = 1 内存中已存在对象1,变量b引用对象1, ...

  7. Async和await关键字的用法

    async & await 的前世今生(Updated) 1. 方法打上Async关键字, 就可以使用await调用别的Async方法了 2. 记得在需要异步执行的方法里面调用await或者n ...

  8. WPF备忘录(4)打个勾画个叉娱乐下

    <Path Grid.Column="2" Data="M43,5 L20,40 20,40 0,20 6,15 18,26 37,7 43,5 z" F ...

  9. 安装svn过程

    1.SVN服务器端程序安装 --检测是否安装成功:svn --version2.创建版本库(仓库) 命令格式:svnadmin create 仓库的目录 3.启动服务器 <1>命令行方式 ...

  10. Docker的下载与安装

    一丶下载 1.win10之外的 Docker下载地址: https://www.docker.com/products/docker-toolbox 2.win10 Docker下载地址: https ...