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

我觉得你还要慎重考虑是否要通过分区来解决查询慢的问题。

因为在tidb中,一般对查询来说分区没有性能回退就不错了。反而需要全局索引来加速分区表的查询。

https://docs.pingcap.com/zh/tidb/stable/partitioned-table/#全局索引

在引入全局索引 (Global Index) 之前,TiDB 会为每个分区创建一个局部索引 (Local Index),即一个分区对应一个局部索引。这种索引方式存在一个使用限制:主键和唯一键必须包含所有的分区键,以确保数据的全局唯一性。此外,当查询的数据跨越多个分区时,TiDB 需要扫描各个分区的数据才能返回结果。

为解决这些问题,TiDB 从 v8.3.0 开始引入全局索引。全局索引能覆盖整个表的数据,使得主键和唯一键在不包含分区键的情况下仍能保持全局唯一性。此外,全局索引可以在一次操作中访问多个分区的索引数据,而无需对每个分区的本地索引逐一查找,显著提升了针对非分区键的查询性能。

最好是能直接把慢查询发出来,大家看看怎么优化,比直接折腾分区可能要更好。
在分区这块,因为tidb底层已经把数据分region存储了,所以不宜参照mysql的优化经验。

1 个赞

这个方法试过了,效果不大,而且 由于条件的不固定,没有确切的一个数据量,那么就需要对不同的条件指定不同的engine。手工hint的方式也试过,对于数据量仅占全表的1%的数据量来说强制走tiflash 就要全表扫描,这样反而更慢

emm,怎么说呢,现在不能从sql的层面进行优化了,由于一张表里面的数据分布不均匀,导致就算条件一样,但是条件的参数不一样,就会出现不同的执行计划。你说的问题我也想过因为tidb底层也是通过region的方式存储,分区效果不大,但是好像也找不到好的方法

那就是需要靠统计信息准确,然后走 cbo 让优化器自己选择了。

建议把这2个执行计划发出来看看,也许能想到更好的办法。

20220830151347 这种完全可以用bigint类型存

RANGE 分区 + 提取年月(前6位)作为分区依据

2 个赞

如果未来数据量很大,可以考虑结合时间范围和 HASH 分区来进一步提升性能。