TDengine 索引使用指南 — 何时建、怎么建、怎么用

发布时间:2026/7/15 3:40:04

TDengine 索引使用指南 — 何时建、怎么建、怎么用 分类9.索引 |篇章03 索引使用指南适用版本TDengine v3.xv3.3.x / v3.4.x | 最后更新2026-07-13索引设计是数据库性能的根基。本文整合 TDengine 多类索引Tag 索引、SMA、TSMA、RSMA的使用决策树给出看到查询模式立刻知道该建什么索引的实用指导。核心概念速查表索引自动/手动加速对象块 SMA自动块级过滤/聚合文件 SMA自动文件级裁剪第一 Tag 索引自动子表筛选额外 Tag 索引手动多 Tag 筛选TSMA手动长期范围聚合RSMA数据库级分层存储详细解析1. 索引决策树查询模式 → 推荐索引 ① WHERE ts T → 块/文件 SMA自动 ② WHERE tag v → Tag 索引 - 第一 Tag默认有 - 其他 Tag手动 CREATE INDEX ③ WHERE current 100 → 块 SMA自动 ④ AVG/SUM/MAX/MIN 简单聚合 → 块 SMA TSMA ⑤ 大时间范围聚合月/年→ TSMA / RSMA ⑥ 子表筛选高基数 Tag → 重新设计 SchemaTag 改为列 ⑦ 复杂表达式聚合 → 流计算2. 实战 1电力监控-- 场景1 亿设备数据常用查询模式-- A. 单设备最近 1 小时数据-- B. 某城市所有设备聚合-- C. 全网日报小时聚合-- 表设计Tag 决定子表数CREATESTABLE meters(tsTIMESTAMP,currentFLOAT,voltageINT)TAGS(cityVARCHAR(32),-- 200 个城市低基数districtVARCHAR(64),-- 几万区县factory_idVARCHAR(32)-- 几十万工厂);-- 子表数 工厂数 × 设备/厂 ≈ 1 亿-- A 查询: WHERE tbnamed001 AND ts now-1h-- → 自动用块 SMA 时间裁剪-- → 单子表查询无需 Tag 索引-- B 查询: WHERE cityBeijing AND ts now-1h-- → 第一 Tag 索引city-- → 自动用块 SMA-- C 查询: SELECT _wstart, AVG(current) FROM meters-- WHERE ts now-1y INTERVAL(1h)-- → 创建 TSMA 加速CREATETSMA meters_1hONmetersFUNCTION(AVG(current),MAX(current),MIN(current))INTERVAL(1h);3. 实战 2IoT 网关数据-- 场景100 万传感器500 种类型-- 常用查询-- A. 单传感器历史-- B. 某类型传感器统计-- C. 异常事件检测CREATESTABLE sensors(tsTIMESTAMP,valueFLOAT,statusTINYINT)TAGS(sensor_typeVARCHAR(32),-- 500 种高频过滤factory_idVARCHAR(32),-- 100 个工厂zone_idVARCHAR(32)-- 几千个区域);-- 默认 sensor_type 索引第一 Tag-- factory_id 是常用过滤 → 显式建索引CREATEINDEXidx_factoryONsensors(factory_id);-- 异常事件流实时CREATESTREAM s_anomalyINTOanomaly_logASSELECT_wstart,tbname,MAX(value)FROMsensorsWHEREstatus1PARTITIONBYtbnameINTERVAL(1m);4. 实战 3金融行情-- 场景5000 只股票秒级行情-- 查询-- A. 单股票日 K-- B. 板块/行业聚合-- C. 全市场指数CREATESTABLE quotes(tsTIMESTAMP,priceFLOAT,volumeBIGINT,...)TAGS(symbolVARCHAR(16),-- 5000 个股票代码一对一子表sectorVARCHAR(32),-- 30 个行业exchangeVARCHAR(16)-- 几个交易所);-- 默认 symbol 索引-- sector 是常用聚合维度CREATEINDEXidx_sectorONquotes(sector);-- 日 K 用 TSMACREATETSMA quotes_1dONquotesFUNCTION(FIRST(price)ASopen,MAX(price)AShigh,MIN(price)ASlow,LAST(price)ASclose,SUM(volume)ASvolume)INTERVAL(1d);-- 历史归档用 RSMA建库时CREATEDATABASEquotes_db RETENTIONS1s:7d,1m:90d,1h:5y;5. 反模式与改进反模式 1: 高基数 Tag CREATE STABLE orders (...) TAGS (user_id BIGINT); -- 1 亿用户 1 亿子表 元数据爆炸 改进 CREATE STABLE orders (...) TAGS (region VARCHAR(32), shard INT); -- user_id 作为普通列 -- shard user_id % 1000 控制子表数 反模式 2: 全字段 Tag CREATE STABLE t (...) TAGS (a, b, c, d, e, f, g, h); -- 过多 Tag 增加元数据 改进 保留 3~5 个常用过滤 Tag其他作普通列 反模式 3: 长字符串 Tag TAGS (description VARCHAR(1024)) -- Tag 值过大索引膨胀 改进 Tag 仅存类别/ID详情存普通列 反模式 4: 复杂查询不命中索引 SELECT * FROM meters WHERE UPPER(location) BEIJING; -- 函数包裹 → Tag 索引失效 改进 SELECT * FROM meters WHERE location beijing; -- 或建表时统一大小写6. 索引维护操作-- 查看索引SHOWINDEXESFROMmeters;SHOWTSMAS;-- 创建索引CREATEINDEXidx_nameONmeters(column);CREATETSMA tsma_nameONmetersFUNCTION(...)INTERVAL(...);-- 删除索引DROPINDEXidx_name;DROPTSMA tsma_name;-- 修改不支持需 DROP 再 CREATE7. 索引性能验证验证流程 ① 准备测试数据 ② EXPLAIN 看计划 ③ EXPLAIN ANALYZE 看实际 ④ 验证关键指标 - blocks_skipped 高 → SMA 生效 - 子表 scan 数量小 → Tag 索引生效 - rows_examined 小 → 索引覆盖好 ⑤ 基准测试对比延迟8. 索引升级策略随业务变化调整 ① 监控慢查询日志 ② 识别高频查询模式 ③ 评估是否缺索引 ④ 在业务低峰创建索引建索引本身耗时 ⑤ 验证查询加速效果 ⑥ 持续观察 何时考虑重构 - 子表数失控亿级以上 - Tag 设计不合理 - 查询模式发生根本变化 重构方案 - 新建表迁移数据 - 或重新 ALTER TABLE 修改 Tag视支持情况代码示例综合应用智慧城市-- 数据库分层存储CREATEDATABASEcity_dbPRECISIONmsKEEP1825RETENTIONS1s:30d,1m:1y,1h:5y;USEcity_db;-- 超级表CREATESTABLE devices(tsTIMESTAMP,valueFLOAT,statusTINYINT)TAGS(districtVARCHAR(32),-- 区device_typeVARCHAR(32),-- 类型vendorVARCHAR(32)-- 厂商)ROLLUP(AVG,MAX,MIN);-- → 自动 RSMA-- 显式索引CREATEINDEXidx_dtypeONdevices(device_type);CREATEINDEXidx_vendorONdevices(vendor);-- TSMA 加速 5 分钟报表CREATETSMA devices_5mONdevicesFUNCTION(AVG(value),COUNT(*))INTERVAL(5m);-- 流计算异常检测CREATESTREAM s_alarmINTOalarm_logASSELECT_wstart,tbname,MAX(value)FROMdevicesWHEREstatus1PARTITIONBYtbnameINTERVAL(10s);性能考量不同索引的成本与收益索引创建成本维护成本查询收益默认 Tag 索引0极低高额外 Tag 索引中低高块 SMA00高TSMA中回填低极高RSMA中低极高流计算替代高中极高索引设计原则原则说明第一 Tag 最重要默认有索引放最常用过滤列额外索引按需不要预先加所有索引TSMA 针对慢查询仅为已知慢查询模式建避免高基数 Tag优先考虑普通列FAQQ1: 索引创建慢怎么办大表新建索引耗时长。建议低峰期执行可考虑表/数据库重建。Q2: 索引和数据存储分离吗Tag 索引在 MNode/VNode 元数据中。SMA 在 .data 文件 Header。TSMA 单独文件。Q3: 每个查询都需要索引吗不需要。简单时间范围查询有自动 SMA 即可。仅在 EXPLAIN 表明扫描过多时才加索引。Q4: 索引数量上限无明确硬上限但过多索引增加写入开销元数据膨胀查询优化器选择慢建议每表 5 个手动索引。Q5: 怎么知道一个查询用了哪个索引EXPLAIN VERBOSE 显示选择的索引和扫描方式。参考系统构架篇01-《TDengine 整体架构全景》02-《集群拓扑深度解析》03-《MNode 内部机制深度解析》04-《RPC 通信层深度解析》05-《VNode 生命周期》06-《RAFT 共识协议》07-《端到端的消息流》数据模型01-《数据库创建与参数详解》02-《超级表/子表/普通表》03-《支持数据类型深度解析》04-《TDengine Tag 设计哲学与 Schema 变更机制》05-《TDengine 虚拟表实现原理》存储引擎01-《TDengine 存储引擎概览》02-《TDengine MemTable 深度解析》03-《TDengine WAL 预写日志机制》04-《TDengine 数据文件格式》05-《TDengine Commit 与 Flush 机制 》06-《TDengine Compaction 合并策略 》07-《TDengine 数据保留与 TTL》08-《TDengine 压缩编码机制》09-《TDengine Cache 与 Last 查询加速》10-《TDengine 逻辑计划生成》查询引擎01-《TDengine 查询引擎概览》02-《TDengine SQL 解析与词法分析》03-《TDengine 语义分析与 AST 重写》04-《TDengine 逻辑计划生成》05-《TDengine 物理计划生成》06-《TDengine 扫描算子》07-《TDengine 聚合算子》08-《TDengine 聚合算子》09-《TDengine 连接算子》10-《TDengine 排序、填充与投影》11-《TDengine 分布式查询执行》12-《TDengine EXPLAIN 与查询优化》数据写入01-《TDengine SQL INSERT》02-《TDengine 无模式写入》03-《TDengine STMT 写入》04-《TDengine 写入内部流程》05-《TDengine 数据更新删除》数据订阅01-《TDengine 数据订阅》02-《TDengine 订阅 vs Kafka》03-《TDengine TMQ 消费流程》04-《TDengine 内部机制》05-《TDengine TMQ 最佳实践》预聚合01-《TDengine RSMA》02-《TDengine TSMA — 时间维度的物化聚合视图》03-《TDengine SMA 内部实现》索引01-《TDengine Tag 索引》02-《TDengine SMA 索引》

相关新闻