当前位置: 首页 > news >正文

TDengine 聚合函数 HYPERLOGLOG 用户手册

在这里插入图片描述

HYPERLOGLOG 函数用户手册(智能电表场景)

1. 函数概述

HYPERLOGLOG 是 TDengine 的聚合函数,用于估算数据集中不重复(去重)元素的数量。该函数基于 HyperLogLog 算法实现,是一种概率性基数估计算法,能够在使用很少内存的情况下,对超大数据集的基数进行估算。

重要说明:

  • TDengine 不支持 COUNT(DISTINCT column) 语法
  • TDengine 不支持在 HYPERLOGLOG 函数内使用 DISTINCT 关键字
  • HYPERLOGLOG 函数本身就具备去重统计功能

2. 语法

SELECT HYPERLOGLOG(column_name) FROM meters [WHERE condition] [GROUP BY clause];

参数说明

  • column_name:需要进行去重计数的字段,支持数值类型、字符串类型和时间戳类型
  • 只接受一个参数,不支持多参数
  • 不支持 DISTINCTHYPERLOGLOG(DISTINCT column_name) 是错误语法

返回值说明

  • 返回类型:BIGINT
  • 返回值意义:估算的不重复元素数量
  • 空值处理
    • 当输入全为 NULL 时,返回 0
    • NULL 值不参与计数,但不影响其他值的计数

3. 算法原理与实际意义

3.1 HyperLogLog 算法原理

HyperLogLog 是一种基于概率的基数估计算法,其核心思想是利用哈希函数的均匀分布特性:

基本原理
  1. 哈希映射:将输入值通过哈希函数映射为固定长度的二进制串
  2. 前导零统计:统计哈希值的前导零个数,前导零越多说明基数越大
  3. 分桶策略:将哈希空间划分为 m 个桶,每个桶记录观察到的最大前导零数
  4. 调和平均:使用调和平均数公式估算基数
数学基础
  • 如果一个数据集的基数为 n,那么其哈希值中约有 n/2 的值第一位为0,n/4 的值前两位为00,以此类推
  • 通过观察前导零的最大长度,可以估算出数据集的规模
  • 使用多个桶降低随机误差,提高估算精度

3.2 算法特点

  • 内存效率:使用固定大小内存(约1.5KB),不随数据量增长
  • 时间复杂度:O(1) 插入和查询时间
  • 精度控制:标准误差约为 1.04/√m,其中m为桶数量(通常为1024或2048)
  • 可合并性:支持分布式计算结果合并
  • 流式处理:支持增量数据处理

3.3 精度分析

根据 HyperLogLog 算法特性:

  • 理论误差:标准误差约为 1.04/√m ≈ 1.6%(m=1024时)
  • 实际误差:在大多数情况下误差在 2% 以内
  • 误差范围:误差随数据量增大而相对减小

3.4 实际应用意义

设备数量统计示例

假设我们要统计一周内有数据上报的电表数量:

-- 传统嵌套查询方法(内存消耗大,查询慢)
SELECT COUNT(*) FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 7d
);-- HYPERLOGLOG 方法(内存消耗小,查询快)
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 7d;

结果对比演示:

  • 实际设备数:10,000 台
  • 嵌套查询结果:10,000 台(精确)
  • HYPERLOGLOG 估算:9,987 台(误差 0.13%)
  • 内存使用对比:嵌套查询可能需要几十MB,HYPERLOGLOG 仅需 1.5KB
  • 查询时间对比:嵌套查询 5000ms,HYPERLOGLOG 50ms
业务价值分析
  1. 实时监控:快速了解设备活跃度,无需精确到个位数
  2. 容量规划:为系统扩容提供参考数据
  3. 趋势分析:识别设备数量变化趋势
  4. 异常检测:快速评估异常影响范围
算法选择策略
-- 小数据集(< 10万条):使用嵌套查询获得精确结果
SELECT COUNT(*) FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 1h
);-- 大数据集(> 100万条):使用 HYPERLOGLOG 获得快速估算
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 30d;-- 中等数据集:根据精度要求选择
-- 需要精确结果时使用嵌套查询
-- 可接受近似结果时使用 HYPERLOGLOG

4. 与 SELECT DISTINCT 的对比分析

4.1 功能对比

特性SELECT DISTINCTHYPERLOGLOG
功能返回不重复的具体值返回不重复值的数量估算
返回类型原字段数据类型BIGINT
内存使用O(n) 线性增长O(1) 固定约1.5KB
计算精度100% 精确约98-99% 精确
性能大数据集时较慢始终高速
结果用途获取具体的不重复值统计分析、监控指标

4.2 语法对比示例

-- SELECT DISTINCT:返回不重复的具体电压值
SELECT DISTINCT voltage FROM meters WHERE ts >= NOW() - 1h;
-- 返回结果:219.8, 220.1, 220.5, 221.2, ... (具体的电压值列表)-- HYPERLOGLOG:返回不重复电压值的数量
SELECT HYPERLOGLOG(voltage) FROM meters WHERE ts >= NOW() - 1h;
-- 返回结果:2847 (表示有约2847个不同的电压值)

4.3 应用场景对比

SELECT DISTINCT 适用场景
-- 获取所有活跃的设备ID列表
SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 24h;
-- 返回:['meter001', 'meter002', 'meter003', ...]-- 获取所有上报数据的区域列表
SELECT DISTINCT location FROM meters WHERE ts >= NOW() - 7d;
-- 返回:['California.SanFrancisco', 'California.LosAngles', 'NewYork.NewYork', ...]-- 获取所有异常电压值
SELECT DISTINCT voltage FROM meters 
WHERE (voltage < 210 OR voltage > 240) AND ts >= NOW() - 24h
ORDER BY voltage;
-- 返回:[195.2, 198.7, 205.1, 241.3, 245.8, ...] (具体异常电压值)
HYPERLOGLOG 适用场景
-- 统计活跃设备数量(用于监控大屏)
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 24h;
-- 返回:8650 (约8650台设备活跃)-- 统计涉及区域数量
SELECT HYPERLOGLOG(location) FROM meters WHERE ts >= NOW() - 7d;
-- 返回:45 (约45个区域有数据)-- 统计异常电压种类数量
SELECT HYPERLOGLOG(voltage) FROM meters 
WHERE (voltage < 210 OR voltage > 240) AND ts >= NOW() - 24h;
-- 返回:127 (约127种不同的异常电压值)

4.4 共同点与区别

共同点
  1. 去重功能:都能识别和处理重复值
  2. NULL处理:都会忽略NULL值
  3. 数据类型支持:都支持数值、字符串、时间戳类型
  4. WHERE条件:都可以配合WHERE条件过滤数据
主要区别

1. 返回内容不同

-- DISTINCT 返回具体值
SELECT DISTINCT groupid FROM meters;
-- 结果:1, 2, 3, 4, 5 (具体的组ID)-- HYPERLOGLOG 返回数量
SELECT HYPERLOGLOG(groupid) FROM meters;
-- 结果:5 (有5个不同的组)

2. 内存消耗差异

-- DISTINCT 在大数据集上内存消耗巨大
SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 30d;
-- 可能需要几百MB内存存储所有设备ID-- HYPERLOGLOG 固定内存消耗
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 30d;
-- 只需要约1.5KB内存

3. 分组聚合的使用

-- DISTINCT 通常不与聚合函数直接组合(TDengine不支持COUNT(DISTINCT))
-- 需要使用嵌套查询实现计数
SELECT COUNT(*) FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 24h
);-- HYPERLOGLOG 直接支持分组聚合
SELECT location, HYPERLOGLOG(device_id) FROM meters 
WHERE ts >= NOW() - 24h 
GROUP BY location;

5. TDengine 中的去重计数实现方式

5.1 错误语法(TDengine不支持)

-- ❌ 错误:TDengine 不支持 COUNT(DISTINCT)
SELECT COUNT(DISTINCT device_id) FROM meters;-- ❌ 错误:HYPERLOGLOG 不支持 DISTINCT
SELECT HYPERLOGLOG(DISTINCT device_id) FROM meters;

5.2 正确的替代方案

方案1:使用 HYPERLOGLOG(推荐)
-- ✅ 推荐:直接使用 HYPERLOGLOG
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 24h;
方案2:使用嵌套查询(精确计数)
-- ✅ 精确计数:嵌套查询实现
SELECT COUNT(*) FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 24h
);
方案3:分组统计
-- ✅ 按区域统计设备数量
SELECT location,HYPERLOGLOG(device_id) AS device_count
FROM meters 
WHERE ts >= NOW() - 7d
GROUP BY location;-- ✅ 嵌套查询方式(精确)
SELECT location,device_count
FROM (SELECT location,COUNT(*) AS device_countFROM (SELECT DISTINCT location, device_id FROM meters WHERE ts >= NOW() - 7d)GROUP BY location
);

6. 返回值实例解析

6.1 基本计数示例

-- 示例数据:device_id 列包含 [1, 2, 2, 3, 3, 3, 4, 5, 5]
SELECT HYPERLOGLOG(device_id) FROM meters;
-- 返回值:5 (表示有5个不重复的设备ID:1,2,3,4,5)-- 对比 SELECT DISTINCT
SELECT DISTINCT device_id FROM meters;
-- 返回值:1, 2, 3, 4, 5 (具体的设备ID列表)

6.2 NULL值处理示例

-- 示例数据:voltage 列包含 [220.1, 219.8, NULL, 220.1, 221.0, NULL, 219.8]
SELECT HYPERLOGLOG(voltage) FROM meters;
-- 返回值:3 (忽略NULL,不重复的电压值:220.1, 219.8, 221.0)-- 对比 SELECT DISTINCT  
SELECT DISTINCT voltage FROM meters WHERE voltage IS NOT NULL;
-- 返回值:219.8, 220.1, 221.0 (具体的电压值)

6.3 分组统计示例

-- 按区域分组统计每个区域的设备数量
SELECT location, HYPERLOGLOG(device_id) FROM meters GROUP BY location;

返回结果:

location                | hyperloglog(device_id)
California.SanFrancisco | 1250
California.LosAngles    | 980  
NewYork.NewYork        | 1150

对比 DISTINCT 方式:

-- 获取每个区域的具体设备列表(嵌套查询实现计数)
SELECT location,COUNT(*) AS device_count
FROM (SELECT DISTINCT location, device_id FROM meters
) 
GROUP BY location;

7. 智能电表应用场景

基于智能电表数据库结构:

CREATE TABLE meters (ts TIMESTAMP,voltage FLOAT,current FLOAT,power FLOAT,device_id VARCHAR(50),region VARCHAR(100)
) TAGS (groupid INT,location VARCHAR(50)
);

7.1 设备统计分析

活跃设备数量统计
-- 统计过去24小时内有数据上报的设备数量
SELECT HYPERLOGLOG(device_id) AS active_devices FROM meters 
WHERE ts >= NOW() - 24h;
-- 返回例如:8650 (约8650台设备活跃)-- 如需具体设备列表,使用 DISTINCT
SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 24h;
-- 返回具体设备ID列表-- 按小时统计活跃设备数量趋势
SELECT _wstart AS hour_time,HYPERLOGLOG(device_id) AS active_devices 
FROM meters 
WHERE ts >= NOW() - 24h
INTERVAL(1h);

7.2 异常事件分析

异常设备统计
-- 统计电压异常的设备数量(快速评估影响范围)
SELECT HYPERLOGLOG(device_id) AS abnormal_devices FROM meters 
WHERE (voltage < 210 OR voltage > 240) AND ts >= NOW() - 24h;
-- 返回例如:125 (约125台设备异常)-- 如需异常设备具体列表(用于维修派单)
SELECT DISTINCT device_id FROM meters 
WHERE (voltage < 210 OR voltage > 240) AND ts >= NOW() - 24h;
-- 返回具体异常设备ID列表-- 统计异常电压值的种类数量
SELECT HYPERLOGLOG(voltage) AS voltage_types FROM meters 
WHERE (voltage < 210 OR voltage > 240) AND ts >= NOW() - 24h;
-- 返回例如:87 (约87种不同异常电压值)

7.3 性能对比实例

-- 大数据集性能对比(假设7天内有1000万条记录)-- 方式1:HYPERLOGLOG(推荐大数据集)
SELECT HYPERLOGLOG(device_id) FROM meters WHERE ts >= NOW() - 7d;
-- 执行时间:约50ms,内存使用:1.5KB,结果:9987-- 方式2:嵌套查询精确计数(小数据集推荐)  
SELECT COUNT(*) FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 7d
);
-- 执行时间:约5000ms,内存使用:几百MB,结果:10000-- 误差分析
SELECT nest_count.exact_count,hll_count.approx_count,ABS(nest_count.exact_count - hll_count.approx_count) AS difference,ABS(nest_count.exact_count - hll_count.approx_count) * 100.0 / nest_count.exact_count AS error_rate
FROM (SELECT COUNT(*) AS exact_count FROM (SELECT DISTINCT device_id FROM meters WHERE ts >= NOW() - 7d)
) nest_count,
(SELECT HYPERLOGLOG(device_id) AS approx_count FROM meters WHERE ts >= NOW() - 7d
) hll_count;
-- 结果示例:exact_count=10000, approx_count=9987, difference=13, error_rate=0.13%

8. 使用注意事项

8.1 语法限制

-- ❌ 错误用法
SELECT HYPERLOGLOG() FROM meters;                    -- 无参数
SELECT HYPERLOGLOG(device_id, location) FROM meters; -- 多参数
SELECT HYPERLOGLOG(DISTINCT device_id) FROM meters;  -- 包含DISTINCT
SELECT COUNT(DISTINCT device_id) FROM meters;        -- TDengine不支持-- ✅ 正确用法
SELECT HYPERLOGLOG(device_id) FROM meters;           -- 单参数
SELECT HYPERLOGLOG(voltage) FROM meters;             -- 数值类型
SELECT HYPERLOGLOG(location) FROM meters;            -- 字符串类型
SELECT HYPERLOGLOG(ts) FROM meters;                  -- 时间戳类型

8.2 场景选择建议

需求推荐方案理由
快速了解数量级HYPERLOGLOG高性能,低内存
需要具体值列表SELECT DISTINCT返回具体内容
精确计数(小数据集)嵌套查询100%准确
实时监控指标HYPERLOGLOG响应快速
报表统计根据精度要求选择平衡性能与精度

8.3 性能优化建议

-- 推荐:合理限制查询范围
SELECT HYPERLOGLOG(device_id) FROM meters 
WHERE ts >= NOW() - 24h AND location = 'California.SanFrancisco';-- 推荐:结合其他聚合函数
SELECT location,COUNT(*) AS total_records,HYPERLOGLOG(device_id) AS unique_devices,AVG(power) AS avg_power
FROM meters 
WHERE ts >= NOW() - 7d
GROUP BY location;

9. 总结

HYPERLOGLOG 函数与 SELECT DISTINCT 在智能电表监控系统中各有优势:

HYPERLOGLOG 优势

  1. 高性能:固定内存使用,适合大数据集
  2. 实时性:快速响应,适合监控指标
  3. 聚合友好:天然支持分组统计
  4. 分布式支持:易于分布式计算
  5. 算法先进:基于概率算法,理论基础扎实

SELECT DISTINCT 优势

  1. 精确性:返回100%准确的具体值
  2. 直观性:结果直观易理解
  3. 灵活性:可用于进一步的数据处理

选择建议

  • 监控指标、趋势分析:使用 HYPERLOGLOG
  • 具体值查询、小数据集:使用 SELECT DISTINCT + 嵌套查询
  • 报表统计:根据精度要求和性能需求选择
  • 大数据集分析:优先使用 HYPERLOGLOG

通过理解 HyperLogLog 算法的原理和特点,结合实际业务需求,可以在保证分析效果的同时最大化系统性能,为智能电表监控系统提供高效的去重统计能力。

关于 TDengine

TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台,其核心模块是高性能、集群开源、云原生、极简的时序数据库。

它能安全高效地将大量设备每天产生的高达 TB 甚至 PB 级的数据进行汇聚、存储、分析和分发,并提供 AI 智能体对数据进行预测与异常检测,提供实时的商业洞察。

http://www.dtcms.com/a/406439.html

相关文章:

  • 威海网站优化公司济南简单的网站制作
  • 书法网站开发的前景西部数码网站管理助手2
  • 使用rabbitmq发送消息时消息体转换报错
  • rabbitmq分布式事务
  • vue动态插槽 #[i] 和 v-slot:[i] 对于Prettier的区别
  • EasyGBS如何构建全域覆盖的应急管理与安全生产解决方案?
  • 【数据结构OJ】BFS算法的可视化:二叉树“层序遍历”
  • RabbitMQ:在Linux上安装RabbitMQ
  • 大数据毕业设计选题推荐:基于Hadoop+Spark的全球能源消耗数据分析与可视化系统
  • 从避障到实时建图:机器学习如何让无人机更智能、更安全、更实用(附微型机载演示示例)
  • ui做的好的网站专业的深圳网站建设公司哪家好
  • 最简单的 Web 打印方案:用 5 分钟上手 web-print-pdf(npm 包)
  • 深度学习在自动驾驶上应用(二)
  • OpenLayers地图交互 -- 章节十二:键盘平移交互详解
  • Unity 透视摄像机视野适配不同分辨率的屏幕
  • 可持续金融的新范式:拆解欧盟ESG监管体系及其全球影响力
  • 【数据保护】一种安全高效的全匿踪纵向联邦学习方法
  • 阿里云物联网平台seo站外优化平台
  • 网站开发软件 手机网站做app有什么意义
  • WorldSimBench: 迈向作为世界模拟器的视频生成模型——论文解读
  • 嵌入式 - 内核驱动1 - 配置linux驱动
  • 工作中学习自己的Qt知识误区-Version3
  • C#连接达梦(DM)数据库
  • 服务器独立显卡可以亮机但进不了系统怎么办
  • 超高密度2kW GaN基低压电机驱动器的设计
  • 「日拱一码」100 机器学习辅助定向进化MLDE
  • C++项目:仿muduo库高并发服务器------EventLoop模块的设计
  • 电子商务网站开发综合实训报告h5页面制作工具包括
  • 全栈信创+AI大模型:百分点科技BD-OS重塑数据治理基座
  • 时隔一天第二阶段他来了 html!!!!!!!!!!!