加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

分享优化MySQL大数据表水平分区的详细方法

发布时间:2023-09-26 15:18:55 所属栏目:MySql教程 来源:
导读:下文主要给大家带来优化MySQL大数据表水平分区的详细方法,希望这些文字能够带给大家实际用处,这也是我编辑优化MySQL大数据表水平分区的详细方法这篇文章的主要目的。好了,废话不多说,大家直接看下文吧。

1.
下文主要给大家带来优化MySQL大数据表水平分区的详细方法,希望这些文字能够带给大家实际用处,这也是我编辑优化MySQL大数据表水平分区的详细方法这篇文章的主要目的。好了,废话不多说,大家直接看下文吧。
 
1. 创建一张分区表
 
这张表的表字段和原表的字段一摸一样,附带分区
 
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语句
 
insert into metric_data_tmp select * from metric_data;
 
数据量非常大,可使用select into outfile, Load data file方式导出导入
 
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. 重命名分区表和历史表:
 
rename table metric_data to metric_data_bak;
 
rename table metric_data_tmp to metric_data;
 
4. 通过数据库的定时任务定时自动创建下月的分区
 
存储过程
 
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 ;
 
创建定时任务,定时执行存储过程创建分区
 
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
 
select
 
    partition_name part,  
 
    partition_expression expr,
 
    partition_description descr,
 
    table_rows  
 
from information_schema.partitions where table_name='metric_data';
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章