You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除WHERE子句后CPU表SQL聚合结果异常,是Bug还是另有原因?

为什么移除WHERE子句后结果完全出乎意料?

执行的SQL及对应结果

SQL 1:无WHERE条件的分组统计

select cpu, count(*) from cpu group by cpu;

查询结果:

+-----------+-----------------+
| cpu       | COUNT(UInt8(1)) |
+-----------+-----------------+
| cpu0      | 1               |
| cpu1      | 1               |
| cpu3      | 1               |
| cpu-total | 1               |
| cpu2      | 1               |
+-----------+-----------------+

SQL 2:带WHERE过滤的分组统计

select cpu, count(*) from cpu where usage_user > 0.1 group by cpu;

查询结果:

+-----------+-----------------+
| cpu       | COUNT(UInt8(1)) |
+-----------+-----------------+
| cpu0      | 40225           |
| cpu-total | 30712           |
| cpu1      | 64182           |
| cpu3      | 51382           |
| cpu2      | 60444           |
+-----------+-----------------+

SQL 3:全表行数统计

select count(*) from cpu;

查询结果:

+-----------------+
| COUNT(UInt8(1)) |
+-----------------+
| 426880          |
+-----------------+

问题

这是Bug吗?还是有合理原因?

表结构说明

该cpu表由Telegraf采集Linux环境监控数据写入,表结构如下:

+------------------+-----------------------+-------------+-------------------+
| COLUMN_NAME      | DATA_TYPE             | COLUMN_TYPE | COMPRESSION_CODEC |
+------------------+-----------------------+-------------+-------------------+
| time             | TIMESTAMP(NANOSECOND) | TIME        | DEFAULT           |
| cpu              | STRING                | TAG         | DEFAULT           |
| host             | STRING                | TAG         | DEFAULT           |
| usage_guest      | DOUBLE                | FIELD       | DEFAULT           |
| usage_guest_nice | DOUBLE                | FIELD       | DEFAULT           |
| usage_idle       | DOUBLE                | FIELD       | DEFAULT           |
| usage_iowait     | DOUBLE                | FIELD       | DEFAULT           |
| usage_irq        | DOUBLE                | FIELD       | DEFAULT           |
| usage_nice       | DOUBLE                | FIELD       | DEFAULT           |
| usage_softirq    | DOUBLE                | FIELD       | DEFAULT           |
| usage_steal      | DOUBLE                | FIELD       | DEFAULT           |
| usage_system     | DOUBLE                | FIELD       | DEFAULT           |
| usage_user       | DOUBLE                | FIELD       | DEFAULT           |
+------------------+-----------------------+-------------+-------------------+

原因解析

这不是Bug,是时序数据库(比如和Telegraf常用搭配的InfluxDB)的存储特性导致的:

  • 表中cpu属于TAG(标签),是用来做索引、分组的元数据;usage_user属于FIELD(字段),是和时间戳绑定的实际监控数据点。
  • 不带WHERE条件的分组查询中,count(*)统计的是每个cpu标签对应的独立时间序列数量——每个cpu值刚好对应一条时间序列,所以结果都是1。
  • 加上WHERE usage_user > 0.1过滤后,查询会扫描实际存储的字段数据,这时的count(*)统计的是满足过滤条件的数据点行数,也就是你预期的实际数据条数。
  • 全表count统计的是所有数据点的总行数,包含那些usage_user不大于0.1的记录,所以数值会比带过滤的分组统计总和大。

内容的提问来源于stack exchange,提问作者learn_more

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 01:44:54