TiDB 的“聚簇因子” -- 从 cop task 到 shard_row_id_bits
作者: pepezzzz 原文来源:https://tidb.net/blog/086d700a
引言
Oracle 的聚簇因子:
表中建立了索引的数据排序优良度的一个度量值;向优化器表明了具有同样索引值的数据行是不是存放在同一个或连续的一系列数据块中,或者数据行是否被分散存放在表的多个数据块中。简单地说,Oracle 数据库的聚簇因子信息,能反映出索引范围扫的回表成本。# 从案例看 cop task## 案例1下图是一个 SQL 的执行计划,选中行是 IndexLookUp 算子回表后过滤算子。从右侧 Operator Info 栏中的可见,416 行的索引回表过滤需要使用 26 的 cop task,可以简单地认为 416 行表数据处于 26 个 region 中。经过数据 “按序” 的导出和导入:a. dumpling --sql “select * from a order by cus_id” -F 100MiB --output-filename-template …b. tidb-lightning下图是 SQL 的新执行计划,执行计划完全一样,效率有较大的提升。
从右侧 Operator Info 栏中的可见,416 行的索引回表过滤仅需要使用 4 的 cop task,可以简单地认为 416 行表数据仅处于 4 个 不同 region 中,相关的数据“聚集”后,回表的开销降低了,网络的请求变快了,高并发情况下尤为明显。## 案例2单表 500 万的数据删除主键后进行“翻数”,重复插入 200 次,得到一个 10 亿记录的表。查询 SQL:select * from t where col1='1' ,col1 列上有二级索引。进行压测时,报:Coprocessor task terminated due to exceeding the deadline。可以认为,由于 10 亿记录的表通过以上的翻数操作得到,数据处于非常 “均匀” 的分散,单条语句的二级索引回表的 cop task 固定为 200,在高并发情况下,极容易触发以上的报错信息。通过相同的“数据整理”步骤,单语句 SQL 效率提升较大。## Region 与 cop taskRegion 是 TiDB 中计算、存储、调度的单元。计算单元的含义,大致可以理解为,cop 请求也会以 region 为单位进行分发。上述案例中,由于数据较为分散,即相同索引值的数据分布在较多的 region 中,会导致单条 SQL 语句的 cop task 变多,影响语句的执行效率,乃至于触发 tikv 的报错。在目前 TiDB 的统计信息设计中,没有类似于 Oracle 的聚簇因子的概念,但是实际上仍受数据 “聚簇” 效果的影响。之前常见于 Oracle 的数据维护操作,对 TiDB 也有相同效果。压测和生产中的高频语句,需要注意相关数据写入分布的行为和影响。# shard_row_id_bitsTiDB v6.5 之前,默认情况下,非整数主键、没有主键的表或者建表时显式指定 nonclustered 非聚簇的表,TiDB 会使用一个隐式的自增 rowid。大量执行 INSERT 插入语句时,由于 rowid 自增分配,会把数据集中写入单个 Region,造成写入热点。通过设置 SHARD_ROW_ID_BITS,可以把 rowid 打散写入多个不同的 Region,缓解写入热点问题。它的使用效果如下图:
隐式的自增 rowid 会因为左侧 shard bits 的翻转,会连续生成 “跳跃” 的 rowid,如 0000...0000,0001...0001,0010...0010,0011...0011,0000...0100,0001...0101,0010...0110 等,得到连续插入数据时,rowid 不连续的效果,规避了写入单个 Region 热点的问题。从上图中,可见 SHARD_ROW_ID_BITS 代表的是 “翻转位数”,2 的幂代表实际 kv map 中的 rowid 写入点数量,即
SHARD_ROW_ID_BITS = 4
表示 16 个分片/ Region。但是,SHARD_ROW_ID_BITS 配置同时会带来写入数据不聚集的问题,从下图中可以看出,同一时间写入的数据,由于 SHARD_ROW_ID_BITS = 2,分布在四个不同的 Region 上。如果语句条件是根据时间进行范围扫,TableRowidScan 算子的 cop task 会增加 3 倍。在生产实践中,关于 SHARD_ROW_ID_BITS 个人的建议是:通常配置为 2写入压力大的情况可以配置为 3不要超过 4另外,如果 tikv 实例的数量较小,不需要配置太大的 SHARD_ROW_ID_BITS。# 结论实际上,TiDB 的“聚簇因子”存在并影响索引读取的效率。在压测和生产实践过程中,需要关注回表数据和 cop task 的大概比例关系。## 题外话 merge_option=deny表属性是 TiDB 从 5.3.0 版本开始引入的新特性。如果建表时指定 shard_row_id_bits 时,希望建表时就均匀切分 Region,可以考虑配合 PRE_SPLIT_REGIONS 一起使用,用来在建表成功后就开始预均匀切分 2^(PRE_SPLIT_REGIONS) 个 Region。但由于新建表或分区的分裂操作实际产生的是空 Region,如果分裂打散操作距离写入存在一定时间间隔,则 Region 可能会被合并,从而导致无法真正规避写入热点问题。此时可以为表或分区添加
merge_option
属性,设置为 deny
来解决问题。- 禁止属于某个表的 Region 被合并
ALTER TABLE t ATTRIBUTES 'merge_option=deny'; ```#

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
天秀 .Net 7 开发者,30 分钟脚本一把梭,并开源
今年的年度 OSC 中国开源项目评选新策划了「最火热中国开源项目社区」奖项,并且增加了全新的“极客”玩法。在此背景下,开发者纷纷施展才华,积极为开源项目贡献“热度值”。 某位开发者在接到操作说明之后,用 .Net 7(C#)在 30 分钟内搞定了 Win 64 和 Linux x64 版本的脚本,并且还有余力进行代码优化。 极具“开源”精神的他更是直接将贡献热度的工具开源了出来:https://gitee.com/maikebing/oschina2022 “热度值”是评选「最火热中国开源项目社区」的核心指标,在评选期间,每个开源项目的主页都会添加 “热度” 挂件,如下图所示: 我们提供了两种方式让用户为开源项目贡献热度。 一、常规方式 用户登录帐号后,点击右侧的蓝色按钮即可为想要支持的开源项目贡献 “热度”。 每点击一次「贡献热度」按钮,随机给该项目的热度值加 1 或 10。该按钮支持连击。请注意:进度圈加载过程中,不要关闭页面,否则会导致丢失 “热度值”。 二、极客玩法 相比常规方式的手动 “点击按钮”,极客玩法让程序员能够用自己擅长的方式来贡献 “热度”,效率更高,更具可玩性。 ...
- 下一篇
sapic(picbed)v1.15 发布,移除 Python 2 支持
sapic(picbed)v1.15 现已发布,具体更新内容包括: 废弃 Python 2 支持,全面转向 Python 3! 移除 Redis 集群模式支持。 配置读取不再兼容picbed前缀。 邮箱激活验证功能所用模块改为PyJWT。 不再同时构建 staugur/picbed 的 Docker Hub 镜像。
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7,CentOS8安装Elasticsearch6.8.6
- MySQL8.0.19开启GTID主从同步CentOS8
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS8安装Docker,最新的服务器搭配容器使用
- Hadoop3单机部署,实现最简伪集群
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2整合Redis,开启缓存,提高访问速度