2024-11-24
中间件
0

目录

基础查询语法
SELECT 语句结构
WHERE 条件筛选
时间范围查询
聚合函数
基本聚合函数
时间窗口聚合
按标签分组
高级查询功能
子查询
数学运算
填充缺失数据
窗口函数和移动计算
移动平均
变化率计算
累积计算
正则表达式和模式匹配
正则表达式查询
LIKE操作符
数据排序和限制
ORDER BY排序
LIMIT限制结果
多表查询和连接
多measurement查询
数据合并
实用查询示例
监控告警查询
性能分析查询
趋势分析查询
查询优化技巧
索引利用
时间范围控制
聚合优化
常见错误和解决方案
语法错误
性能问题
数据类型问题
命令行查询实践
使用influx CLI
HTTP API查询

数据写进去了,接下来就是把它们查出来。InfluxDB 使用 InfluxQL 作为查询语言,语法类似SQL,但专门为时间序列数据优化过。

如果你熟悉SQL,学 InfluxQL 会很快上手。如果不熟悉也没关系,我们从基础开始。

基础查询语法

InfluxQL 基础查询语法结构示意图,展示了 SELECT 语句的组成部分、常见查询模式以及 WHERE 子句的使用方法

image.png

SELECT 语句结构

InfluxQL 的基本结构和SQL很像:

sql
SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>]

最简单的查询:

sql
-- 查询所有字段 SELECT * FROM temperature -- 查询特定字段 SELECT value FROM temperature -- 查询多个字段 SELECT value, humidity FROM temperature

WHERE 条件筛选

sql
-- 按标签筛选 SELECT * FROM temperature WHERE location = 'room1' -- 按时间筛选 SELECT * FROM temperature WHERE time >= '2023-01-01T00:00:00Z' -- 组合条件 SELECT * FROM temperature WHERE location = 'room1' AND time >= now() - 1h

时间范围查询

时间是时序数据的核心,InfluxQL 提供了灵活的时间查询:

sql
-- 查询最近1小时的数据 SELECT * FROM temperature WHERE time >= now() - 1h -- 查询特定时间段 SELECT * FROM temperature WHERE time >= '2023-01-01T00:00:00Z' AND time <= '2023-01-01T23:59:59Z' -- 查询最近7天 SELECT * FROM temperature WHERE time >= now() - 7d -- 查询今天的数据 SELECT * FROM temperature WHERE time >= now() - 1d

时间单位很丰富:

  • s 秒
  • m 分钟
  • h 小时
  • d 天
  • w 周

聚合函数

InfluxQL 聚合函数和时间窗口示意图,展示了基本聚合函数的使用方法、GROUP BY TIME的工作原理以及不同时间窗口粒度的性能对比

image.png

基本聚合函数

InfluxQL 提供了丰富的聚合函数:

sql
-- 计算平均值 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h -- 计算最大值和最小值 SELECT MAX(value), MIN(value) FROM temperature WHERE time >= now() - 1h -- 计算总和 SELECT SUM(value) FROM temperature WHERE time >= now() - 1h -- 计算数量 SELECT COUNT(value) FROM temperature WHERE time >= now() - 1h -- 计算标准差 SELECT STDDEV(value) FROM temperature WHERE time >= now() - 1h

时间窗口聚合

GROUP BY TIME 是 InfluxQL 的核心功能,用来按时间窗口聚合数据:

sql
-- 按5分钟窗口计算平均值 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m) -- 按1小时窗口计算最大值 SELECT MAX(value) FROM temperature WHERE time >= now() - 1d GROUP BY time(1h) -- 按天计算平均值 SELECT MEAN(value) FROM temperature WHERE time >= now() - 30d GROUP BY time(1d)

按标签分组

除了时间,还可以按标签分组:

sql
-- 按location分组 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY location -- 按时间和标签同时分组 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m), location -- 多个标签分组 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY location, sensor_type

高级查询功能

InfluxQL 高级查询功能示意图,展示了子查询、数学运算和数据填充等高级功能的使用方法和应用场景

image.png

子查询

InfluxQL 支持子查询,用来处理复杂的数据分析:

sql
-- 查询高于平均温度的数据点 SELECT * FROM temperature WHERE value > ( SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h ) -- 查询每小时最高温度的时间点 SELECT * FROM ( SELECT MAX(value) FROM temperature WHERE time >= now() - 1d GROUP BY time(1h) )

数学运算

可以对字段进行数学运算:

sql
-- 温度单位转换(摄氏度转华氏度) SELECT value * 9/5 + 32 AS fahrenheit FROM temperature -- 计算温湿度指数 SELECT value + humidity * 0.1 AS comfort_index FROM temperature -- 计算变化率 SELECT DERIVATIVE(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(1m)

填充缺失数据

时序数据经常有缺失值,可以用FILL来处理:

sql
-- 用前一个值填充 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m) FILL(previous) -- 用线性插值填充 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m) FILL(linear) -- 用固定值填充 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m) FILL(0) -- 不填充(默认) SELECT MEAN(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(5m) FILL(null)

窗口函数和移动计算

InfluxQL 窗口函数和移动计算示意图,展示了移动平均、导数计算和累积计算等窗口函数的工作原理和应用场景

image.png

移动平均

sql
-- 5点移动平均 SELECT MOVING_AVERAGE(value, 5) FROM temperature WHERE time >= now() - 1h -- 指数移动平均 SELECT EXPONENTIAL_MOVING_AVERAGE(value, 5) FROM temperature WHERE time >= now() - 1h

变化率计算

sql
-- 计算导数(变化率) SELECT DERIVATIVE(value) FROM temperature WHERE time >= now() - 1h GROUP BY time(1m) -- 计算非负导数 SELECT NON_NEGATIVE_DERIVATIVE(value) FROM cpu_usage WHERE time >= now() - 1h GROUP BY time(1m) -- 计算差值 SELECT DIFFERENCE(value) FROM temperature WHERE time >= now() - 1h

累积计算

sql
-- 累积和 SELECT CUMULATIVE_SUM(value) FROM rainfall WHERE time >= now() - 1d -- 积分计算 SELECT INTEGRAL(value) FROM power_consumption WHERE time >= now() - 1d GROUP BY time(1h)

正则表达式和模式匹配

正则表达式查询

sql
-- 匹配特定模式的标签值 SELECT * FROM temperature WHERE location =~ /room[0-9]+/ -- 不匹配特定模式 SELECT * FROM temperature WHERE location !~ /test.*/ -- 匹配多个measurement SELECT * FROM /temperature|humidity/ WHERE time >= now() - 1h

LIKE操作符

sql
-- 模糊匹配 SELECT * FROM temperature WHERE location LIKE 'room%' -- 不匹配 SELECT * FROM temperature WHERE location NOT LIKE 'test%'

数据排序和限制

ORDER BY排序

sql
-- 按时间升序(默认) SELECT * FROM temperature ORDER BY time ASC -- 按时间降序 SELECT * FROM temperature ORDER BY time DESC -- 按字段值排序 SELECT * FROM temperature ORDER BY value DESC

LIMIT限制结果

sql
-- 限制返回条数 SELECT * FROM temperature LIMIT 100 -- 跳过前N条记录 SELECT * FROM temperature LIMIT 100 OFFSET 50 -- 获取最新的10条记录 SELECT * FROM temperature ORDER BY time DESC LIMIT 10

多表查询和连接

多measurement查询

sql
-- 查询多个measurement SELECT * FROM temperature, humidity WHERE time >= now() - 1h -- 使用正则表达式查询多个measurement SELECT * FROM /temperature|humidity/ WHERE time >= now() - 1h

数据合并

虽然InfluxQL不支持传统的JOIN,但可以用其他方式合并数据:

sql
-- 在应用层合并不同measurement的数据 -- 或者使用Flux查询语言(InfluxDB 2.0+)

实用查询示例

监控告警查询

sql
-- 查找温度异常的时间点 SELECT * FROM temperature WHERE value > 30 OR value < 10 -- 查找CPU使用率持续高于80%的时间段 SELECT MEAN(cpu_percent) FROM cpu_usage WHERE time >= now() - 1h GROUP BY time(5m) HAVING MEAN(cpu_percent) > 80

性能分析查询

sql
-- 计算响应时间的95百分位数 SELECT PERCENTILE(response_time, 95) FROM api_requests WHERE time >= now() - 1h GROUP BY time(5m) -- 查找最慢的请求 SELECT * FROM api_requests WHERE time >= now() - 1h ORDER BY response_time DESC LIMIT 10

趋势分析查询

sql
-- 计算同比增长率 SELECT MEAN(value) FROM sales WHERE time >= now() - 7d GROUP BY time(1d) -- 计算移动平均趋势 SELECT MOVING_AVERAGE(MEAN(value), 7) FROM temperature WHERE time >= now() - 30d GROUP BY time(1d)

查询优化技巧

InfluxQL 查询优化技巧对比图,展示了推荐与不推荐的查询方式对比,以及各种优化策略的性能影响分析

image.png

索引利用

sql
-- 好的查询:利用标签索引 SELECT * FROM temperature WHERE location = 'room1' AND time >= now() - 1h -- 避免:对字段进行范围查询 SELECT * FROM temperature WHERE value > 25 -- 这会很慢

时间范围控制

sql
-- 总是指定时间范围 SELECT * FROM temperature WHERE time >= now() - 1h -- 避免查询全部历史数据 SELECT * FROM temperature -- 这可能很慢

聚合优化

sql
-- 使用适当的时间窗口 SELECT MEAN(value) FROM temperature WHERE time >= now() - 1d GROUP BY time(1h) -- 而不是 GROUP BY time(1s)

常见错误和解决方案

InfluxQL 常见错误诊断与解决方案图,展示了语法错误、性能问题和数据类型问题的诊断流程以及相应的解决方案

image.png

语法错误

sql
-- 错误:忘记引号 SELECT * FROM temperature WHERE location = room1 -- 正确:字符串要加引号 SELECT * FROM temperature WHERE location = 'room1' -- 错误:时间格式不对 SELECT * FROM temperature WHERE time > '2023-01-01' -- 正确:使用完整的时间格式 SELECT * FROM temperature WHERE time > '2023-01-01T00:00:00Z'

性能问题

sql
-- 问题:查询范围太大 SELECT * FROM temperature WHERE time >= '2020-01-01T00:00:00Z' -- 解决:限制时间范围 SELECT * FROM temperature WHERE time >= now() - 7d -- 问题:没有使用标签筛选 SELECT * FROM temperature WHERE value > 25 -- 解决:先用标签筛选,再用字段筛选 SELECT * FROM temperature WHERE location = 'room1' AND value > 25

数据类型问题

sql
-- 错误:标签值用数字比较 SELECT * FROM temperature WHERE room_number > 5 -- 正确:标签值是字符串 SELECT * FROM temperature WHERE room_number = '5'

命令行查询实践

使用influx CLI

sh
# 进入 InfluxDB 命令行 influx -host localhost -port 8086 # 选择数据库(InfluxDB 1.x) USE mydb # 执行查询 SELECT * FROM temperature WHERE time >= now() - 1h; # 格式化输出 SELECT * FROM temperature WHERE time >= now() - 1h FORMAT json;

HTTP API查询

sh
# 使用curl查询 curl -G 'http://localhost:8086/query' \ --data-urlencode "db=mydb" \ --data-urlencode "q=SELECT * FROM temperature WHERE time >= now() - 1h" # InfluxDB 2.0 API curl -XPOST 'http://localhost:8086/api/v2/query' \ -H 'Authorization: Token your-token' \ -H 'Content-Type: application/vnd.flux' \ -d 'from(bucket:"mybucket") |> range(start:-1h) |> filter(fn:(r) => r._measurement == "temperature")'

掌握了InfluxQL,你就能从时序数据中挖掘出有价值的信息了。下一篇我们会学习聚合函数的高级用法,让数据分析更加强大。

本文作者:柳始恭

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!