升级 lq_restock

第一步:修改表结构

根据 keytime 来设置分区,需要合理设置 keytime
(如果已经存在 create_time 且 完全可以按照 create_time 设置分区,就不需要新建字段了)

# 创建用于分区的分割字段(lq_key_time)
alter table lq_restock_logs add lq_key_time datetime default now() not null;
alter table lq_restock_passenger add lq_key_time datetime default now() not null;

# 设置 lq_key_time 为创建时间
UPDATE lq_restock_logs p INNER JOIN lq_restock_order o ON p.order_id= o.id SET p.lq_key_time = o.create_time;
UPDATE lq_restock_passenger p INNER JOIN lq_restock_order o ON p.order_id= o.id SET p.lq_key_time = o.create_time;

# 删除原主键
alter table lq_restock_order drop primary key;
alter table lq_restock_logs drop primary key;
alter table lq_restock_passenger drop primary key;

# 创建联合主键
alter table lq_restock_order add PRIMARY KEY(id, create_time);
alter table lq_restock_logs add PRIMARY KEY(id, lq_key_time);
alter table lq_restock_passenger add PRIMARY KEY(id, lq_key_time);

第二步:创建分区表

创建老数据的分区,其他的数据全部放到 a1 中,后续拆分 a1 来实现分区。
每个月拆一次,超过12个月的可以合并到年分区

# 创建分区
ALTER TABLE `lq_restock_order`  PARTITION BY RANGE(TO_DAYS(create_time)) (
    PARTITION p2018 VALUES LESS THAN (TO_DAYS('2019-01-01')) ENGINE = INNODB,
    PARTITION p2019 VALUES LESS THAN (TO_DAYS('2020-01-01')) ENGINE = INNODB,
    PARTITION p2020 VALUES LESS THAN (TO_DAYS('2021-01-01')) ENGINE = INNODB,
    PARTITION p2021 VALUES LESS THAN (TO_DAYS('2022-01-01')) ENGINE = INNODB,
    PARTITION p2022 VALUES LESS THAN (TO_DAYS('2023-01-01')) ENGINE = INNODB,
    PARTITION p2023 VALUES LESS THAN (TO_DAYS('2023-02-01')) ENGINE = INNODB,
    PARTITION a1 VALUES LESS THAN  MAXVALUE
);

ALTER TABLE `lq_restock_logs`  PARTITION BY RANGE(TO_DAYS(lq_key_time)) (
    PARTITION p2018 VALUES LESS THAN (TO_DAYS('2019-01-01')) ENGINE = INNODB,
    PARTITION p2019 VALUES LESS THAN (TO_DAYS('2020-01-01')) ENGINE = INNODB,
    PARTITION p2020 VALUES LESS THAN (TO_DAYS('2021-01-01')) ENGINE = INNODB,
    PARTITION p2021 VALUES LESS THAN (TO_DAYS('2022-01-01')) ENGINE = INNODB,
    PARTITION p2022 VALUES LESS THAN (TO_DAYS('2023-01-01')) ENGINE = INNODB,
    PARTITION p2023 VALUES LESS THAN (TO_DAYS('2023-02-01')) ENGINE = INNODB,
    PARTITION a1 VALUES LESS THAN  MAXVALUE
);

ALTER TABLE `lq_restock_passenger`  PARTITION BY RANGE(TO_DAYS(lq_key_time)) (
    PARTITION p2018 VALUES LESS THAN (TO_DAYS('2019-01-01')) ENGINE = INNODB,
    PARTITION p2019 VALUES LESS THAN (TO_DAYS('2020-01-01')) ENGINE = INNODB,
    PARTITION p2020 VALUES LESS THAN (TO_DAYS('2021-01-01')) ENGINE = INNODB,
    PARTITION p2021 VALUES LESS THAN (TO_DAYS('2022-01-01')) ENGINE = INNODB,
    PARTITION p2022 VALUES LESS THAN (TO_DAYS('2023-01-01')) ENGINE = INNODB,
    PARTITION p2023 VALUES LESS THAN (TO_DAYS('2023-02-01')) ENGINE = INNODB,
    PARTITION a1 VALUES LESS THAN  MAXVALUE
);

第三步:查看分区情况

分析一下分区,可以看到分区的数据情况

#分析
ALTER TABLE lq_restock_order ANALYZE PARTITION p2018,p2019,p2020,p2021,p2022,p2023,a1;

# 查看全部分区
SELECT table_name,partition_name,partition_description,from_days(partition_description),table_rows
FROM information_schema.PARTITIONS
WHERE table_name='lq_restock_order';

# 分析
explain select * from lq_restock_order where create_time>'2023-1-1' and create_time<'2023-6-10';

附:后续

时间越来越长后会导致 a1 分区越来越大,需要将 a1 的数据拆分出来,比如6个月前的放到各自的分区中
例如(下例的 2023 和 202309 可以动态获取(p2023已经包含1-8月的数据)):

# 从 a1 中拆分出9月的放到p202309和其他的继续放到a1
alter table lq_restock_order reorganize partition a1 into (
    PARTITION p202309 VALUES LESS THAN (to_days('2023-10-01')),
    PARTITION a1 VALUES LESS THAN  MAXVALUE
);

# 合并 p2023,p202309 到 p2023
alter table lq_restock_order reorganize partition p2023,p202309 into (
    PARTITION p2023 VALUES LESS THAN (to_days('2023-10-01'))
);

# 重新分析
ALTER TABLE lq_restock_order ANALYZE PARTITION p2023,a1;
posted @ 2023-05-22 16:17  ddgo's  阅读(11)  评论(0编辑  收藏  举报
.