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

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

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. RETE算法介绍

    RETE算法介绍一. rete概述Rete算法是一种前向规则快速匹配算法,其匹配速度与规则数目无关.Rete是拉丁文,对应英文是net,也就是网络.Rete算法通过形成一个rete网络进行模式匹配,利 ...

  2. java web 机试

    经过近一个月的学习,我们的java web已经学习完了. 这是我们这次的机试题. 一:题目 请利用MVC设计模式,并使用JSP.Servlet.JSTL和JQuery等技术实现动态条件的分页显示查询. ...

  3. 百度全站 https FAQ:技术宅告诉你如何搜索更安全

    百度从 14 年开始对外开放了 https 的访问,并于 3 月初正式对全网用户进行了 https 跳转. 你也许会问,切换就切换呗,和我有啥关系?我平常用百度还不是照常顺顺当当的,没感觉到什么切换. ...

  4. LVS持久化与超时时间问题分析

    前言 在上一篇文章<搭建DNS+LVS(keepAlived)+OpenResty服务器(Docker环境)>中,我搭建了dns+lvs+openresty+web集群:先来回顾一下架构图 ...

  5. ffplay源码分析4-音视频同步

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10307089.html ffplay是FFmpeg工程自带的简单播放器,使用FFmpeg ...

  6. 小程序实例:用js方法splict()、indexOf()、push()、replace()等操作数组Array的增删改查

    一.增加数组子级 1.Array.push() 定义和用法 向数组的末尾处添加一个或多个子集,并返回新数组的长度 语法 var array=["好","扎在那个" ...

  7. PBN飞越转弯Flyover衔接TF、CF航段保护区组图

    PBN飞越转弯Flyover衔接TF.CF航段虽不常用,但也很重要,与旁切转弯有一定的相似性. 飞越转弯 flyover-TF/CF 叠加图: 飞越转弯 flyover-TF/CF 分解图:

  8. 深入出不来nodejs源码-events模块

    这一节内容超级简单,纯JS,就当给自己放个假了,V8引擎和node的C++代码看得有点脑阔疼. 学过DOM的应该都知道一个API,叫addeventlistener,即事件绑定.这个东西贯穿了整个JS ...

  9. WPF TreeView 选择事件执行两次,获取TreeView的父节点的解决方法

    1.TreeView选择事件执行两次 Very often, we need to execute some code in SelectedItemChanged depending on the ...

  10. MarkdownPad编写博客技巧笔记

    说明 想约束自己使用博客来记录自己的内容,发现CSDN能导入.md文件,就查了查使用方式,发现确实比较好用的,本文档就是使用MarkdownPad编写,生成.md上传的.记录下使用方法 Markdow ...