关于tidb主键前缀匹配的问题

【 TiDB 使用环境】生产环境
【 TiDB 版本】 5.4
请问各位,如果主键用的业务的唯一键,当使用前缀匹配做查询的时候,性能如何呢?跟普通的二级索引精准查询相对比有优势吗。

背景:有字段unique_id,而order_no字段是其固定的前缀,案例为unique_id=‘test-123’,order_no=‘test’【unique_id非顺序增加写入的,是乱序的,同一个order_no开头的unique_id几乎不可能短期内大量写入,不会存在热点问题,一个order_no对应的多个的unique_id通常小于10个】。
业务上order_no是高频的查询场景,但order_no又不是唯一的,不能直接作为主键和聚簇索引

场景一:字段unique_id作为主键,查询时均用unique_id前缀匹配来查询。
场景二:随机的自生成id作为主键,对order_no建立索引,使用order_no精准匹配查询。
请问各位,这两种场景理论上哪种性能更好,在百亿量级数据存储下的搜索性能差距会较大吗?谢谢

如果场景一是前缀匹配,那性能应该不如场景二

我们前缀匹配可能查出来的数据量不会很大,小于等于10条,因为我看官方文档在存储一节的描述:“按照 Key 分 Range,某一段连续的 Key 都保存在一个存储节点上”,并且对于聚簇索引一节的描述:“等值或范围条件查询仅涉及主键的前缀时会减少多次从网络读取数据”。我所以才对这一点存在疑问,如果绝大多数的场景下前缀匹配的结果都在一个Region,感觉对比场景二可能查询需依赖多个Region而言,性能更高哇

你unique_id是字符串格式的吗,还是数字格式的?

是字符串格式的。
案例(从上之下顺序也可能是实际写入的顺序,并不能保证其中唯一键的整体规律,唯一的规律就是前缀一定是这行数据的订单号 test):
【unique_id】 【order_no】
【test-sh-100 】【test】
【test-bj-010】【test】
【test-sh-90】【test】
【test-sh-110 】【test】

但是你场景一用字段unique_id作为主键,但是它并不能当key 啊,tidb会自动生成_tidb_rowid作为key值啊,你如果不用shard_row_id_bits功能确实这些数据会在一个region里面,但是会产生写热点问题吧?

是的,我们不打算用shard_row_id_bits,打算就把主键作为聚簇索引,写热点问题应该是不存在的,因为我们业务场景上同一个order_no的多条数据不会在短期内产生,产生肯定是有较大时间间隔的

那可能场景一应该好一点,但实际场景二也有优势,就是他其实这些数据可能是存在多个region多个节点的,也就是可以通过多个tikv节点并行获取数据,应该也不会特别慢

但是有一些存疑的细节,例如在like的时候如果只提供了前缀,tidb能快速定位这些数据所在的region吗?不太确定聚簇索引的前缀匹配和普通的索引在查询时的路由逻辑

这种用法应该类似Point_Get吧,直接通过key来查询tikv上的数据后返回,普通索引是先通过索引获取到对应数据的key然后通过key去查询tikv上的数据,再返回

主键的前缀匹配搜索原理还是不太理解。。主键都不确定完整的情况下,如何定位的region呢,tidb的文档中也没有发现提到过类似prefix Bloom filter的结构

可以建表测试下,我这里测试是把字符串主键作为聚簇索引,前缀like查询的话,不会回表,会直接通过key获取

好的,那执行计划中能看出来实际一共扫描了多少个region吗。感谢您帮我们测试,这个问题我们这边现在决定建2个表导亿级数据做下实际的各方面指标对比了,除了性能可能还需要评估下实际业务中把唯一键当主键的集群稳定性,实际的差距可能跟很多方面有关,还是得实际用案例跑一下

扫描了多少key是会返回的,但是多少个region看不出来,不过肯定是实验出真知,实际评估下是最好的。

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。