优化 Flux 查询
此页面记录了早期版本的 InfluxDB OSS。InfluxDB OSS v2 是最新的稳定版本。请参阅 InfluxDB v2 文档。
优化您的 Flux 查询以降低其内存和计算 (CPU) 要求。
使用下推功能启动查询
下推功能是将数据操作推送到底层数据源而不是在内存中操作数据的功能或功能组合。使用下推功能启动查询以提高查询性能。一旦非下推功能运行,Flux 会将数据拉入内存并在那里运行所有后续操作。
下推功能和功能组合
以下下推功能在 InfluxDB OSS 1.11+ 中受支持。
函数 | 支持 |
---|---|
count() | |
drop() | |
duplicate() | |
filter() * | |
fill() | |
first() | |
group() | |
keep() | |
last() | |
max() | |
mean() | |
min() | |
range() | |
rename() | |
sum() | |
window() | |
功能组合 | |
group() |> max() | |
group() |> min() | |
window() |> count() | |
window() |> first() | |
window() |> last() | |
window() |> max() | |
window() |> min() | |
window() |> sum() |
* filter() 仅当所有参数值都是静态的时,才会下推。请参阅 避免内联处理过滤器。
在查询的开头使用下推功能和功能组合。一旦非下推功能运行,Flux 会将数据拉入内存并在那里运行所有后续操作。
正在使用的下推功能
from(bucket: "db/rp")
|> range(start: -1h) //
|> filter(fn: (r) => r.sensor == "abc123") //
|> group(columns: ["_field", "host"]) // Pushed to the data source
|> aggregateWindow(every: 5m, fn: max) //
|> filter(fn: (r) => r._value >= 90.0) //
|> top(n: 10) // Run in memory
避免内联处理过滤器
避免使用数学运算或字符串操作内联定义数据过滤器。内联处理过滤器值会阻止 filter() 将其操作下推到底层数据源,因此前一个函数返回的数据会加载到内存中。这通常会导致显著的性能下降。
例如,以下查询使用 Chronograf 仪表板模板变量和字符串连接来定义要过滤的区域。因为 filter() 内联使用字符串连接,所以它无法将其操作下推到底层数据源,并将从 range() 返回的所有数据加载到内存中。
from(bucket: "db/rp")
|> range(start: -1h)
|> filter(fn: (r) => r.region == v.provider + v.region)
为了动态设置过滤器并保持 filter() 函数的下推能力,请使用变量在 filter() 之外定义过滤器值
region = v.provider + v.region
from(bucket: "db/rp")
|> range(start: -1h)
|> filter(fn: (r) => r.region == region)
避免过短的窗口持续时间
窗口化(基于时间间隔分组数据)通常用于聚合和降采样数据。通过避免过短的窗口持续时间来提高性能。更多的窗口需要更多的计算能力来评估每行应分配给哪个窗口。合理的窗口持续时间取决于查询的总时间范围。
谨慎使用“重型”函数
以下函数比其他函数使用更多的内存或 CPU。在使用它们之前,请考虑它们在数据处理中的必要性
尽可能使用 set() 而不是 map()
set()
, experimental.set()
, 和 map
都可以设置数据中的列值,但是 set 函数比 map()
具有性能优势。
使用以下指南来确定使用哪个
- 如果将列值设置为预定义的静态值,请使用
set()
或experimental.set()
。 - 如果使用现有行数据动态设置列值,请使用
map()
。
将列值设置为静态值
以下查询在功能上是相同的,但使用 set()
比使用 map()
性能更高。
data
|> map(fn: (r) => ({ r with foo: "bar" }))
// Recommended
data
|> set(key: "foo", value: "bar")
使用现有行数据动态设置列值
data
|> map(fn: (r) => ({ r with foo: r.bar }))
平衡时间范围和数据精度
为了确保查询性能,请平衡时间范围和数据精度。例如,如果您查询每秒存储的数据并请求六个月的数据,则结果将包含每个序列约 1550 万个点。根据 filter()(基数) 后返回的序列数量,这可能很快变成数十亿个点。Flux 必须将这些点存储在内存中才能生成响应。使用 下推功能来优化存储在内存中的点数。
使用 Flux 性能分析器测量查询性能
使用 Flux Profiler 包来测量查询性能并将性能指标附加到您的查询输出。以下 Flux 性能分析器可用
- query:提供有关整个 Flux 脚本执行的统计信息。
- operator:提供有关查询中每个操作的统计信息。
导入 profiler
包并使用 profile.enabledProfilers
选项启用性能分析器。
import "profiler"
option profiler.enabledProfilers = ["query", "operator"]
// Query to profile
有关 Flux 性能分析器的更多信息,请参阅 Flux Profiler 包。
此页面对您有帮助吗?
感谢您的反馈!