1.背景
数据建模对于数据库建立后整体高效运行非常关键,不同建模方式,可能会产生相差几倍的性能差别
2. 建库
建模在建库阶段应考虑几下几点:
建多少库
根据业务情况确定建库个数,TDengine 不支持跨库查询,如果业务数据之间会发生相互查询,那就需要把这些数据设计在一个库中,根据业务的独立性创建相应数据库,数据库个数多少不会对性能产生大的影响。
建库语法
CREATE DATABASE [IF NOT EXISTS] db_name [database_options]database_option: {VGROUPS value| DURATION value| KEEP value| WAL_RETENTION_PERIOD value| WAL_RETENTION_SIZE value...
}
参数说明
这里说下几个重点参数
VGROUPS
VGROUPS 是数据分区参数,一个 VGROUP 相当于一个分区,多分区可进行并发写入及查询,此参数是数据库最重要并发性能参数。
- 一个 VGROUP 承载的子表数最好规划在 100 万内最佳
- VGROUPS 建立后不能再减小,只能增加,增加的方式只能通过分裂方式,把一个 VGROUP 一分为二,子表数平均到分裂后的两个 VGROUP 中(分裂功能仅企业版提供)
DURATION
Duration 决定了生成文件组的数量,经验表明,在磁盘资源固定,同时打开写入文件的数量越少写入性能越高,调整此参数,让引擎生成的 data 文件不要太碎,提升读写性能。原则上数据写入越密集,就应调小此参数值,写入数据越稀疏,越应调大此值。
KEEP
表示数据文件保存天数,这个参数根据业务情况给定,今后也可以通过 alter database
动态调整,这个参数只会影响占用磁盘空间大小,对性能无影响
WAL_RETENTION_PERIOD
WAL 保留周期,这个参数主要用于订阅消费,如果有订阅业务,可以根据业务期望保留周期设定。设定周期过长时 WAL 会占用大量磁盘空间,需要注意。
WAL_RETENTION_SIZE
WAL 保留大小,如果磁盘空间有限,使用 WAL_RETENTION_PERIOD
参数又无法估算 WAL 会占用多大,那可以考虑使用此参数保留 WAL 文件占用磁盘大小
3. 建表
CREATE STABLE [IF NOT EXISTS] stb_name (create_definition [, create_definition] ...) TAGS (create_definition [, create_definition] ...) [table_options]
TDengine 中有三种表,超级表,子表和普通表,常用的是超级表及子表,普通表很少使用。超级表规划时,注意以下几点:
- 一个数据库中包括的超级表个数是没有限制的,常见的是规划几十、几百个,规划过多对性能没有太大影响,但查询时会带来一些不方便
- 超级表之间查询只有少量 SQL 语句支持,一般查询都发生在超级表内进行的,规划时要注意
- 建表列数最大 4096 列,最佳性能普通列在 1000 列内,超过 1000 列性能会有较大影响,TAG 列个数对性能影响不大
4. 写入
规划数据写入时注意以下几点:
- 切忌不要乱序写入,乱序写入性能会很差而且会占用超大磁盘空间。
乱序是针对同一个子表时间主列而言, 不同子表之间不存在乱序。如无法避免乱序,最好集中写一段时间范围内数据,不要做交叉写,如可以先把前天数据集中写完,再写昨天数据,不要写一条昨天的,又写一条前天的,再来一条昨天的,这样写的性能会非常差。 - 规划好写入方式
写入方式性能最好的是 native 方式,但 native 方式依赖客户端版本,如果服务器升级了,客户端也需要跟着一起升级。官方推荐使用 WebSocket 方式写入, WebSocket 写入对客户端依赖小,服务器升级影响,同时性能也能达到 native 方式的 70% ~ 90% 左右
5. 查询
统计查询是最终目的,所以查询需求一定程序上决定了构架及建模
规划数据查询时注意以下几点:
- 查询占用资源多,耗用内存大,规划时尽量错峰查询,避免集中在一点导致内存不足
- 常用聚合类查询可规划预计算模式
计算一次后结果保留,再次查询无需再计算。TDengine 提供了两种预计算技术,一种是 流计算 , 另一种是 TSMA(仅企业版支持),可根据自己业务查询频率规划一定的预计算查询。