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

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

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. Python核心编程 | 装饰器

        装饰器是程序开发的基础知识,用好装饰器,在程序开发中能够提高效率 它可以在不需要修改每个函数内部代码的情况下,为多个函数添加附加功能,如权限验证,log日志等   涉及点:   1.先梳理一下 ...

  2. find_package()的查找*.cmake的顺序

    1. find_package(<Name>)命令首先会在模块路径中寻找 Find<name>.cmake,这是查找库的一个典型方式.具体查找路径依次为CMake: 变量${C ...

  3. MathType试用期到了如何继续用

    1,卸载原来的MathType(不知道需不需要,其实删不删应该无所谓吧) 2,删除注册表中的一个值(不是默认,而是另外一个值) HKEY_CURRENT_USER\Software\Install O ...

  4. CentOS6.5 QT5.3 找不到GLIBCXX3.4.15解决方法

    下载安装后 启动的时候提示 GLIBCXX_3.4.15,发现libstdc++.so.6的版本过, 在安装qt-creator的时候运行这个IDE就出现了这个问题,是由于libstdc++.so.6 ...

  5. Python模块: 命令行解析optionparser

    Python 有两个内建的模块用于处理命令行参数:一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数:另一个是 optparse,它功能强大,而 ...

  6. POJ 2349 Arctic Network(最小生成树中第s大的边)

    题目链接:http://poj.org/problem?id=2349 Description The Department of National Defence (DND) wishes to c ...

  7. 一:MyBatis知识整理(1)

    一:MyBatis的架构 1.mybatis配置SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息. mapper.xml文件即sql映射文 ...

  8. 【Java并发编程】10、Java 理论与实践: 正确使用 Volatile 变量

    转自:http://www.importnew.com/15842.html Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchron ...

  9. Java代码优化笔记

    指定类.方法的final修饰符 为类指定final修饰符可以让类不可以被继承,为方法指定final修饰符可以让方法不可以被重写.如果指定了一个类为final,则该类所有的方法都是final的.Java ...

  10. python学习之老男孩python全栈第九期_day009之初始函数初窥

    '''# len# 计算字符串的长度# s = '金老板小护士'# len(s)# 不能用 len 怎么办#low一点的方法# count = 0# for i in s:# count += 1# ...