tidb数据表用你自增好,还是random好

random好吧

如果不是要求极限的写入速度,那就自增,自增默认每个tidb节点不同自增值,可以加参数统一成一个

深分页也是可以用auto_random

random

根据业务需求设计

根据业务需求和集群环境情况。大多情况下,auto_increment可以满足需求!

看业务

根据业务来看吧,自增有可能写热点,random 范围读不太好

可以用自增,但表结构要改一下。

https://docs.pingcap.com/zh/tidb/stable/high-concurrency-best-practices

如果表没有主键或者主键不是整数类型,而且用户也不想自己生成一个随机分布的主键 ID 的话,TiDB 内部有一个隐式的 _tidb_rowid 列作为行 ID。在不使用 SHARD_ROW_ID_BITS 的情况下,_tidb_rowid 列的值基本也为单调递增,此时也会有写热点存在(参阅 SHARD_ROW_ID_BITS 的详细说明)。

要避免由 _tidb_rowid 带来的写入热点问题,可以在建表时,使用 SHARD_ROW_ID_BITSPRE_SPLIT_REGIONS 这两个建表选项(参阅 PRE_SPLIT_REGIONS 的详细说明)。

需要使用非聚簇表+SHARD_ROW_ID_BITS+PRE_SPLIT_REGIONS来消除写入热点。

非聚簇表写入性能差很多,原来插入是1条数据,非聚簇是两条数据。
做写入压测,非聚簇表写入速度跌50%

1 个赞

测试报告能发下吗,理论上不会有这么大差异,一个索引损失50%

尽量不要使用自增,否则批量新增或导入时容易出现热点

业务需求来了

聚簇表:

CREATE TABLE `ticket2` (
  `draw_id` int(11) NOT NULL,
  `ticket_no` varchar(30) NOT NULL ,
  `clerk_id` int(11) unsigned NOT NULL,
  `ticket_pwd` varchar(40) NOT NULL ,
  `sale_time` datetime NOT NULL ,
  `chances` int(11) unsigned NOT NULL ,
  `selection` varchar(4000) NOT NULL ,
  `multiple` int(11) unsigned NOT NULL ,
  `bno` int(11) unsigned DEFAULT NULL ,
  `eno` int(11) unsigned DEFAULT NULL ,
  `transaction_id` int(11) DEFAULT NULL ,
  `term_id` int(11) unsigned DEFAULT NULL ,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY (`draw_id`,`ticket_no`) /*T![clustered_index] CLUSTERED */
)
CREATE TABLE `ticket3` (
  `draw_id` int(11) NOT NULL ,
  `ticket_no` varchar(30) NOT NULL ,
  `clerk_id` int(11) unsigned NOT NULL ,
  `ticket_pwd` varchar(40) NOT NULL,
  `sale_time` datetime NOT NULL ,
  `chances` int(11) unsigned NOT NULL ,
  `selection` varchar(4000) NOT NULL ,
  `multiple` int(11) unsigned NOT NULL ,
  `bno` int(11) unsigned DEFAULT NULL ,
  `eno` int(11) unsigned DEFAULT NULL  ,
  `transaction_id` int(11) DEFAULT NULL 
  `term_id` int(11) unsigned DEFAULT NULL ,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`draw_id`,`ticket_no`) NONCLUSTERED
)  SHARD_ROW_ID_BITS = 4,pre_split_regions=4 ;

分别用sysbentch 512线程写入 ,性能差距巨大
聚簇表

[ 10s ] thds: 512 tps: 67619.90 qps: 67620.20 (r/w/o: 0.00/67620.20/0.00) lat (ms,95%): 11.04 err/s: 0.00 reconn/s: 0.00
[ 20s ] thds: 512 tps: 66567.43 qps: 66567.33 (r/w/o: 0.00/66567.33/0.00) lat (ms,95%): 11.04 err/s: 0.00 reconn/s: 0.00
[ 30s ] thds: 512 tps: 69296.34 qps: 69296.24 (r/w/o: 0.00/69296.24/0.00) lat (ms,95%): 10.84 err/s: 0.00 reconn/s: 0.00
[ 40s ] thds: 512 tps: 60856.48 qps: 60856.38 (r/w/o: 0.00/60856.38/0.00) lat (ms,95%): 13.95 err/s: 0.00 reconn/s: 0.00

非聚簇表

[ 10s ] thds: 512 tps: 22846.68 qps: 22846.88 (r/w/o: 0.00/22846.88/0.00) lat (ms,95%): 28.16 err/s: 0.00 reconn/s: 0.00
[ 20s ] thds: 512 tps: 19491.95 qps: 19491.85 (r/w/o: 0.00/19491.85/0.00) lat (ms,95%): 41.10 err/s: 0.00 reconn/s: 0.00
[ 30s ] thds: 512 tps: 19342.19 qps: 19342.09 (r/w/o: 0.00/19342.09/0.00) lat (ms,95%): 38.94 err/s: 0.00 reconn/s: 0.00

除了搞过js的限制转了string以外,还是用的auto_random居多,分散热点,提供更好的性能才是重点

random 能够避免热点问题。TiDB官方也推荐。

只能说random相对好一点吧。热点问题也不是用了random就一定能避免的。

你的自增ID没有业务属性,最好使用random

random

在TiDB中,选择使用自增ID还是随机ID取决于具体的应用场景和性能考虑。每种方法都有其优势和劣势。

自增ID

优势:

  • 可预测性:自增ID提供了一个连续的、易于理解的标识符序列。
  • 简单性:对于一些应用场景,自增ID可以简化数据的管理和引用。

劣势:

  • 热点问题:在TiDB中,使用自增ID可能会导致热点问题。因为TiDB是分布式数据库,数据是根据行的主键来分布在不同的Region上的。如果使用自增ID,新插入的行总是在表的末尾,这可能导致写入操作集中在少数Region上,形成写热点,影响数据库的整体性能。

随机ID

优势:

  • 避免热点问题:随机ID可以帮助避免热点问题,因为新插入的行会被均匀分布在多个Region上,从而使得写入负载更加均衡。
  • 安全性:随机ID在某些情况下可以提供更好的安全性,因为它们不容易被预测。

劣势:

  • 可读性差:相比于自增ID,随机ID的可读性差,不易于人类理解。
  • 管理复杂性:使用随机ID可能会增加数据管理的复杂性,尤其是在需要手动引用特定记录的场景中。

解决热点问题的策略

如果选择使用自增ID,TiDB提供了一些策略来解决或减轻热点问题:

  • 使用AUTO_RANDOM关键字:在TiDB 3.1.0及更高版本中,可以使用AUTO_RANDOM关键字为表的主键列自动生成随机ID,这有助于减轻由于连续自增ID导致的热点问题。
  • 手动分散热点:通过在应用层实现自定义的ID生成逻辑,如在自增ID的基础上加上一定的随机或散列因子,来避免写入热点。

总的来说,选择自增ID还是随机ID,应该基于你的应用场景和对性能的需求来决定。如果你的应用可以容忍热点问题或者写入负载不是特别高,自增ID可能是一个简单有效的选择。如果你的应用需要高并发写入,考虑使用随机ID或者采取策略来避免热点问题可能会更合适。