varchar类型的字段如何用作分区键

我有一张表
create table t1 (oid varchar(32),dt varchar(20),otime varchar(32) primary key oid)

otime里面存储的是年月日时分秒格式 类似于:20220830151347

如果我要按照月份进行分区 比如 20220830151347 放到p08 分区

请教一下如何使用 otime 字段作为分区键


直接这样建就可以,但是要满足插入的数据格式严格满足要求

否则就会发现在对应分区找不到数据

1 个赞

字符串分总能插进去吧

CREATE TABLE t1 (
oid VARCHAR(32),
dt VARCHAR(20),
otime VARCHAR(32),
PRIMARY KEY (oid)
)
PARTITION BY RANGE (TO_DAYS(STR_TO_DATE(otime, ‘%Y%m%d%H%i%s’)))
(
PARTITION p01 VALUES LESS THAN (TO_DAYS(‘2022-02-01’)),
PARTITION p02 VALUES LESS THAN (TO_DAYS(‘2022-03-01’)),
PARTITION p03 VALUES LESS THAN (TO_DAYS(‘2022-04-01’)),
PARTITION p04 VALUES LESS THAN (TO_DAYS(‘2022-05-01’)),
PARTITION p05 VALUES LESS THAN (TO_DAYS(‘2022-06-01’)),
PARTITION p06 VALUES LESS THAN (TO_DAYS(‘2022-07-01’)),
PARTITION p07 VALUES LESS THAN (TO_DAYS(‘2022-08-01’)),
PARTITION p08 VALUES LESS THAN (TO_DAYS(‘2022-09-01’)),
PARTITION p09 VALUES LESS THAN (TO_DAYS(‘2022-10-01’)),
PARTITION p10 VALUES LESS THAN (TO_DAYS(‘2022-11-01’)),
PARTITION p11 VALUES LESS THAN (TO_DAYS(‘2022-12-01’)),
PARTITION p12 VALUES LESS THAN (TO_DAYS(‘2023-01-01’))
);

你可以尝试一下,我这边测试6.5是没有问题的

那你得建个默认分区,不在间隔分区内的,保证数据能进去…

类似于
min ---------- current ---------- max

要对时间轴的数据分段,不然会有毛病了…

1 个赞

加一个字段月份

要么函数转换后做范围分区,要么把varchar改成时间类型(或者创建一个类似虚拟机列的时间类型的字段)

可以尝试在表结构中添加一个虚拟生成列generated column,该列从otime 字段提取出年份和月份信息,然后基于这个新列进行分区。

虚拟列要在建表的时候就创建,不支持通过alter table进行创建

这个方式是按照年月进行分区,这个没啥问题。正常是可以用,但是以月份为分区的话,就要用到虚拟列 获取月份,然后通过月份进行分区。看来我要重建表了

你这样建立分区,要解决什么问题?

查询慢的问题

我打算转类型做分区

什么样的 SQL?你测试过了建立了分区,查询就快了?

你可以使用 otime 字段配合 CAST(otime AS UNSIGNED) 表达式作为 RANGE 分区键,并按月份定义分区范围,例如将 20220830151347 格式的数据划分到 p08 分区。

对的,就剩下分区没测了,如果分区不行就要分表了,我们一张表的数据倾斜太严重了,就算上了tiflash 遇见数据量较小的条件也会走到tikv,包括不同的索引也试过了,也达不到理想的效果

数据量小走 tikv ,这是正常的啊

1 个赞

问题就在这边,数据量大 就算有索引 也会很慢

如果固定走 tiflash 就指定下 engine 或者加个 hint。
https://docs.pingcap.com/zh/tidb/stable/use-tidb-to-read-tiflash/

1 个赞