TiDB 单表200亿如何提高性能?

业务方有分库分表在用,主要是这个查询频率很低,一小时没几次查询。业务方感觉分库分表的成本有点高,想降成本,如果搞成5副本,比原来的2副本几乎差不多了。感觉不好办了。

1 个赞

如果是这种sql的话,那还是走tiflash比较合理

估计只能这样了。纯tikv感觉挺难的。曾经我以为tidb一出,分库分表就得靠边站,现在看来分库分表也有些场景比较适合,比如说这个业务,分库分表可以把数据按照预期存放,每一个查询所有节点都能参与进来,这点tidb好像还做不到。

其实tikv还行,底层会把数据自动切片打散,只要资源能横向扩展,性能和表数据量无关。

tikv做不到一条sql把所有tikv都查询起来。像这个场景,查询频率很低,数据不一定哪一片是热的。可能一天的数据就分布在了两三台tikv上,查询的时候无法充分利用所有tikv把数据快速查询出来。

这个其实不难。最简单的做法来个auto random+聚簇表就可以了。

不想改表结构,还可以试试这个。
https://docs.pingcap.com/zh/tidb/stable/follower-read#follower-read
数据leader可能确实集中在几台,但follower就不一定在哪里了。

这个按createTime搞聚簇表吗?

CREATE TABLE test (
id varchar(32) NOT NULL,
no varchar(50) DEFAULT NULL,
mode varchar(50) NOT NULL,
type varchar(50) NOT NULL,
createTime datetime NOT NULL,
updateTime datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id,createTime) /*T![clustered_index] NONCLUSTERED */,
KEY idx_createTime (createTime),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin /*T! SHARD_ROW_ID_BITS=4 PRE_SPLIT_REGIONS=4 */

非聚簇表+SHARD_ROW_ID_BITS 打散,或者

CREATE TABLE test (
pk bigint(20) AUTO_RANDOM NOT NULL,
id varchar(32) NOT NULL,
no varchar(50) DEFAULT NULL,
mode varchar(50) NOT NULL,
type varchar(50) NOT NULL,
createTime datetime NOT NULL,
updateTime datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (pk) /*T![clustered_index] CLUSTERED */,
unique key(id,createTime)
KEY idx_createTime (createTime),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

聚簇表+auto random 打散。

你每天的数据量都有1-4亿,我很难想象表结构不出问题的话,这些数据会集中在其中的1-3台tikv上。
我上面那个2.6亿的表,就是 NONCLUSTERED +SHARD_ROW_ID_BITS =3.按天查也不会出现有其他tikv在围观别的tikv干活的情况。时间片再小一点到是有可能。

2 个赞

不过像你这个表的话,我建议修改下SHARD_ROW_ID_BITS ,让数据尽可能的打散一下,否则你一个时间段内的数据可能都集中在一个region上
ALTER TABLE t SHARD_ROW_ID_BITS = 4;—这样会生成16个分片

2 个赞

存了什么东西, 搞那么多数据

存的钱 :grinning:,数据量大的库多的是,这是很常见的。

1 个赞

只有本地索引没有全局索引

一天的数据可能就集中在一两台机器上
这个也不可能发生的,你一天数据量上亿了,少说也有几十个regions。
查询慢考虑优化索引,比如加联合索引

我这有张表250亿条记录了,是一个明细表查询频率非常高,没有分区表没有tiflash,所有查询必须走索引,不允许聚合查询,不允许做统计分析,一点问题没有。
image

1 个赞

点查吗?有范围查询吗?

数据同步到大数据,那里做分析,tidb里面只给用户查询明细

控成本比较严重情况下,分布式数据库发挥不了优势,不适合很多场景。

数据量太大,按时间索引其实效率也不高

刚好有过维护超级大表的经历,之前管理的集群,有一个表单表共约90TB、共500亿行,每天flink实时写入1~5亿行日志数据,只保留最近两年的数据,这里可以分享一下经验。

对于这种超级大表,单表200亿行,要结合业务好好设计一下。

从存储的角度来看:

  • tidb底层自动划分Region,自动均衡分配,不用介入管理,可以说是天然合适存储这种大表的。
  • 如果大部分时间是冷数据、少部分是温数据、热数据,可以考虑冷热存储分离https://tidb.net/blog/387bd516,即冷数据放在超级大的HDD盘,热数据放在SSD。可以极致的降低存储成本

从业务使用的角度来看:

  • 如果你是纯粹点查场景、或者是小范围时间轻量聚合场景,没有清理历史数据的需求,可以就建立一个实体表;
  • 如果你有比较相对较多的AP统计,那么建议你也上tiflash添加列存副本,加速分析;
  • 如果你的表有定期清理大量数据的需求,那么强烈建议使用分区表,如果是有过期时间则可以按createTime进行range分区,在SQL查询使用时必须要带上分区键进行过滤,以达到高效检索。

结论是,对于超级大表的存储,已经有不少用户实践经验,是一个可靠的方案。最近知乎代晓磊老师的文章,里面也要这个案例,也可以参考知乎TiDB分享:知乎有一个最大的 TiDB 集群有 500 多 TB 的规模,单副本一天能存 30TB 数据,三副本能存将近 100TB 左右。

3 个赞