Tdengine按TAG查询和按照子表查询差别巨大

【TDengine 使用环境】
生产环境

【TDengine 版本】

3.4.0

【操作系统以及版本】

CentOS7.9

【部署方式】容器/非容器部署

非容器

【集群节点数】
3

【集群副本数】

单副本

【描述业务影响】

【问题复现路径/shan】做过哪些操作出现的问题

【遇到的问题:问题现象及影响】

CREATE TABLE d_20 USING ts_kv (device_id) TAGS (20)

SELECT time, tag_id ,tag_value FROM ts_kv where device_id = 20 and tag_id = “480000” ORDER BY time DESC LIMIT 1

查询时间10s+

SELECT time, tag_id ,tag_value FROM d_20 where tag_id = “480000” ORDER BY time DESC LIMIT 1
查询时间100ms

为什么第一种查询性能是全表扫描,device_id 是TAG字段,device_id = 20不应该直接定位到d_20子表再进行查询吗

【资源配置】

【报错完整截图】(不要大段的粘贴报错代码,论坛直接看报错代码不直观)

explain analyze verbose true select……

这两条sql都按照以上方式执行下,拿下输出

和我说的一样,第一个走的是全表扫描

还是那个问题,为什么没有直接定位到d_20子表再进行查询

我本地验证了下是按照tag条件进行找表了的,将完整的查询计划粘贴出来一下吧

你环境有多少张子表,然后再执行下select distinct tbname from ts_kv where device_id=20 and tag_id=”48000” 看下输出

show create table ts_kv看下输出

CREATE STABLE ts_kv (time TIMESTAMP, tag_id VARCHAR(256) COMPOSITE KEY, tag_value NCHAR(256)) TAGS (device_id INT)
第一个报异常,这是第二个查询结果

一个设备一张子表,并用device_id作为这个表的TAG,每个设备表中存储采集点的时序数据,tag_id表示采集点id,tag_value表示采集值

发一下完整的explain analyze verbose select查询计划输出内容,粘贴出来下吧

select distinct tbname from ts_kv where device_id=20 and tag_id=”48000”

查询单表时order by 首列 desc+ limit 是有优化的,反向扫描d_20这张表会很快找到最后一条数据

使用超级表时用tag定位到d_20这种表后,再进行desc+limit会扫描d_20全表数据

解决方案:

  1. 使用超级表扫描时,加上时间范围,减少扫描的数据量
  2. 可以尝试使用last_row

select last_row(time),tag_id,tag_value,device_id from ts_kv

where device_id IN (20)

AND tag_id IN (‘475011’,‘475880’,‘476090’,‘477040’,‘488919’)

PARTITION BY device_id, tag_id
我就是因为,想要查询设备下不同点位的最新值,last_row需要搭配group by或者PARTITION BY 性能太差所有才只能通过上面方法查询的,没想到查询还是太慢。

查询单表有优化,为什么查询超表没有优化

@KianWang 请回复一下