shard_row_id_bits使用原理咨询

tidb版本为V3.0.3

背景: shard_row_id_bits=4 ,tikv有3个节点

1:请问将t表的shard_row_id_bits设置为4时,是在3个tikv节点上预分配16个region吗?平均每个tikv节点有5到6个region,是这么理解吗? 如果某个tikv上分配的某region满了,这个时候是重新在该节点上新分配一个region吗,还是在3个tikv上重新再预分配16个新的region呢? 后面每次分配region的策略是固定的1个或者16个吗

2:mysql推荐每个表要使用主键 ,tidb有推荐使用主键的最佳实践吗?如果使用shard_row_id_bits参数,就只能是配合唯一索引来使用了

谢谢

不是,这个是内部打散 row-key 。split region 是另外一个打散热点的方法

有的,最佳实践文档已经很多了,尤其针对读写热点的,你可以看看 Asktug 相关的技术文章,另外推荐你阅读一下 TiDB-in-Action https://book.tidb.io/session4/chapter7/hotspot-resolved.html

以及 PU 的业务开发课程

1: 看了文档shard_row_id_bits参数说明,如上截图,"16个分片"指的的是16个region吗?

2: 一个业务t表目前表大小2亿+,需要增加一个联合索引

alert table t add index idx(mid,is_bot,is_deleted,create_at);

其中mid为smallint类型不是主键字段,is_bot和is_deleted为tinyint类型,create_at为timestamp类型

split table操作只对新写入的索引数据产生效果吗? 表中已存在的历史数据如何按照索引切分策略生效呢?

SPLIT TABLE INDEX idx BETWEEN (10000,0,0,“2019-06-01 00:00:00”) AND (200000,0,0,“2022-01-01 00:00:00”) REGIONS 12;

索引第一个字段mid唯一值比较少,但每个值的行数很多,第二第三个字段值基本上都为0,第四个字段create_at为数据入库时间。业务sql查询中,前3个字段为等值查询,第四个字段为范围查询。

执行以上索引切分策略后,对于mid相同的索引数据会放在同一个Region中,region满了后如果继续分裂,会放同一个tikv上,是这样的吗?

策略a: SPLIT TABLE INDEX idx BETWEEN (10000) AND (200000) REGIONS 12;

策略b: SPLIT TABLE INDEX idx BETWEEN (10000,0,0,“2019-06-01 00:00:00”) AND (200000,0,0,“2022-01-01 00:00:00”) REGIONS 12;

索引切分策略a与b,只考虑4个字段的只读场景,哪一种策略更合适,性能更好呢?

谢谢

你好,

正在分析,请稍等~

好的。对于idx索引,业务场景如下,如果这个mid最近7天的数据在同一个region里,性能应该是最好的,那如何设计SPLIT TABLE INDEX达到最好的性能呢? 谢谢

select count(*) from t where mid=12345 and is_bot=0 and is_deleted=0 and create_at <= now()-7天;

  1. 是16个region
  2. 对历史数据也有效
  3. region分裂后不一定在一个tikv
  4. 如果前三个等值,还有很多其他值,那么可以考虑策略a
  5. 可以按照7天来分region,但是这样要提前划出reigon,另外,您的索引是按照时间单调递增写入吗?这样可能会有写入热点. 即使按照7天来分,如果这7天超过了region size的大小也可能会分裂。

行记录和create_at索引是按照时间单调递增写入。

select count(*) from t where mid=12345 and is_bot=0 and is_deleted=0;

总记录是100W。业务场景一般只关心最近7天的,大概5W左右,7天以前的数据查询的概率很小。

目前表里有mid字段索引了,不过偶尔会出现大于5秒的慢查询(目前是5个tivk节点),打算尝试添加(mid,is_bot,is_deleted,create_at)组合索引看看性能如何

  1. 你的目的主要是查看这个sql,你可以尝试下组合索引是否就可以满足要求。
  2. 你的场景随着时间不断推移,数据量就会变化,每天都在变,这样划分split region不大好划分。 除非不断的去手工调整,有些麻烦。 你可以先尝试按照10天这样为一个region,是否能够满足系统要求,多谢
1赞

好的 多谢

:call_me_hand::call_me_hand::call_me_hand: