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_BITS
和PRE_SPLIT_REGIONS
这两个建表选项(参阅PRE_SPLIT_REGIONS
的详细说明)。
需要使用非聚簇表+SHARD_ROW_ID_BITS+PRE_SPLIT_REGIONS来消除写入热点。
非聚簇表写入性能差很多,原来插入是1条数据,非聚簇是两条数据。
做写入压测,非聚簇表写入速度跌50%
测试报告能发下吗,理论上不会有这么大差异,一个索引损失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或者采取策略来避免热点问题可能会更合适。