InfluxDB的查询优化

news2024/11/29 3:45:15

首先,在学习influxDB的查询优化之前,我们要先学习下InfluxDB的解释器profiler(类似于mysql的Explain语句,不一样的是,sql,hivesql是提前查看执行计划等,Influx是在当前查询的最后一页两张表),能够很好的帮助我们理解和查看执行步骤计划,从而优化你的查询语句
我们先来看看官网是如何解释的:
Use the Flux Profiler package to measure query performance and append performance metrics to your query output. The following Flux profilers are available:
使用 Flux 探查器包测量查询性能并将性能指标追加到查询输出

一、如何使用InfluxDB的查询优化器:profiler

1,先看官网的解释

image.png

import "profiler"

option profiler.enabledProfilers = ["query", "operator"]

// Query to profile

2,在脚本编辑器中添加依赖后点击submit,并翻到最后一页

在这里插入图片描述

3,如何看懂执行计划

简单来说,query代表提供有关整个 Flux 脚本执行的统计信息。operator 提供有关查询中每个操作的统计信息。相当于算子,类似于Map-Reduce
下面是官网的具体解释

  • query: provides statistics about the execution of an entire Flux script.
  • operator: provides statistics about each operation in a query.

需要注意的是,这里的时间都代表纳秒,long类型,我们需要使用工具将时间转换成秒,由上图可以看出此查询执执行0.022891
在这里插入图片描述

下面贴出来所有字段的明细解释:

1,query
TotalDuration查询总持续时间(以纳秒为单位)
CompileDuration编译查询脚本所花费的时间(以纳秒为单位)
QueueDuration排队所花费的时间(以纳秒为单位)
RequeueDration重新排队花费的时间(以纳秒为单位)
PlanDuration计划查询所花费的时间(以纳秒为单位)
ExecuteDuration执行查询所花费的时间(以纳秒为单位)
Concurrency并发,分配给处理查询的 goroutines。
MaxAllocated查询分配的最大字节数(内存)
TotalAllocated查询时分配的总字节数(包括释放然后再次使用的内存)
RuntimeErrors查询执行期间返回的错误消息
flux/query-planflux 查询计划
influxdb/scanned-values数据库扫描磁盘的数据条数
influxdb/scanned-buytes数据库扫描磁盘的字节数
2,operator
Type操作类型
Label标签(标明执行步骤)
count执行这个操作的总次数
MinDuration操作被执行多次中,最快的一次花费的时间(以纳秒为单位)
MaxDuration操作被执行多次中,最慢的一次花费的时间(以纳秒为单位)
DurationSum当前操作完成的总持续时间(以纳秒为单位)。
MeanDuration操作被执行多次的平均持续时间(以纳秒为单位)。

我简单标注几个,给大家参考:
在这里插入图片描述

二、flux语句的查询优化

先看官网给出的,由于InfluxDB是时序数据库,存储数据是按照一个个序列来存的,所以,通过存储时间序列的方式来存储对应value,这样能大大的提高效率,为了减少CPU和内存的占用,Influx的语句执行也是有相应的要求,接下来我们分五种方式来分析
在这里插入图片描述

1,谓词下推(Pushdowns

什么是谓词?比如:select * from tbl1 where a>1,那么谓词就是指的是a>1,简单理解为就是查询条件

Use pushdown functions and function combinations at the beginning of your query. Once a non-pushdown function runs, Flux pulls data into memory and runs all subsequent operations there.(在查询开始时使用下推函数和函数组合。一旦非下推函数运行,Flux 就会将数据拉入内存并在那里运行所有后续操作)

下推是将数据操作推送到基础数据源而不是对内存中的数据进行操作的函数或函数组合。使用下推启动查询以提高查询性能。一旦非下推函数运行,Flux 就会将数据拉入内存并在那里运行所有后续操作
简单理解:尽量少的使用内存,在数据进入内存之前进行操作,提前将a>1的数据筛选出来再拉入内存计算
官网给出了用于谓词下推的函数:
在这里插入图片描述

注意:由于InfluxDBcloud版本收费,部分函数不支持谓词下推
在这里插入图片描述

接下来通过有下推和无下推的两条Flux脚本,查看profliler对比一下
1:在filter中过滤measurement

import "profiler"

option profiler.enabledProfilers = ["query", "operator"]

from(bucket: "test_compute")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "cpu")

在这里插入图片描述

2:在filter中过滤measurement,但是cpu我是用字符串来拼接,意思就是说我在执行filter之前又进行了一步计算

import "profiler"

option profiler.enabledProfilers = ["query", "operator"]

from(bucket: "test_compute")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "cp"+"u")

在这里插入图片描述

从上面可以看出来,2计划的operator执行了两步,query查询,2计划执行了2854297710NS->2.8543 S,1计划执行了48421932 Ns ->0.048422s,相差了大概60倍的差距,目前测试环境的数据不大,如果数据量大的时候差距还会越来越大
在这里插入图片描述

接下里我们再使用谓词下推的函数看一下,可以发现operator执行了一步,查询cpu时一共用时82201876 ns-> 0.08秒
在这里插入图片描述

总结:
由上可以看出,谓词下推会大大提高我们的执行效率,所以,我们再filter() 等函数里面切记不要进行复杂计算,在平时工作中使用尽量使用简短明确的表达式,要动态设置过滤器并保持 filter() 函数的下推功能,使用变量在 filter() 之外定义过滤器值
下面给出官网的示例:
在这里插入图片描述

2,避免窗口时间过小

窗口化(根据时间间隔对数据进行分组)通常用于聚合和缩减数据采样。通过避免较短的窗口持续时间来提高性能。更多的窗口需要更多的计算能力来评估每行应分配给哪个窗口。合理的窗口持续时间取决于查询的总时间范围。

窗口设置为1分钟 ->172590080 纳秒 = 0.17259 秒
在这里插入图片描述

窗口设置为10分钟->109932001 纳秒 = 0.109932 秒
在这里插入图片描述

窗口设置为30s->291565458 纳秒 = 0.291565 秒
在这里插入图片描述

窗口设置为10s->1009266800 纳秒 = 1.0093 秒
在这里插入图片描述

从上面可以看出,窗口越小时,执行时间越长,所以我们再实际工作中不要把window开的过小,窗口过小对应的时间序列就会增多,查询也就越慢,当然,窗口也不是越长越好,要根据实际工作中,结合项目的采集周期合理开窗,我们也可以通过开窗来进行降采样,让每个窗口计算出max()或者min() mean()等再插入另外一个存储桶进行存储
这里再解释下关于窗口函数的两种方式:
window 函数和 aggregateWindow 函数,两者不 同的地方在于,window 函数会将整个表流重新分组。window 开窗后,是按照序列+窗口的 方式对整个表流进行分组。但是 aggregateWindow 函数会保留原来的分组方式,这样一来, 使用 aggregateWindow 函数进行开窗后的表流,仍然是按照序列的方式来分组的。我们平时应使用aggregateWindow()来提高效率

3、避免使用沉重的功能

这里的“沉重”意义理解为Hadoop生态中的MapReduce.要进行分组->聚合->合并->再分组->再聚合,对于大数据量来说,正是因为要产生大量计算才有spark的RDD,广播变量,共享内存等等,然而对于时序数据库来说,这些明显是不可取的。
官方解释:要避免使用 map() reduce() join() union() pivot()等函数,这些都会大大增加cpu或者内存的消耗,以map()为例来说。map会将所有的序列重新遍历一遍
下面我们用pofilter来测试一下

import "profiler"

option profiler.enabledProfilers = ["query", "operator"]

from(bucket: "test_compute")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "cpu")
  |> map(fn: (r) => ({r with temp:"213423"}))

在这里插入图片描述

在这里插入图片描述

可以看到,我将cpu查询出来后map()再增加一列数据temp:value,query执行要400919449 纳秒 = 0.400919 秒oprator是两个,去掉map()后只有一个operator,query执行是44931928 纳秒 = 0.044932 秒
我们可以明显的对比来效率,但是官方还是在一直优化(极有可能也是采用分布式的计算,通过共享变量等减小内存或者cpu的开销)
在这里插入图片描述

4,尽可能使用 set()而不是 map()

如果你要给数据查一个静态常量,那么 set 比 map 要有很大的性能优势。set(): 如果将列值设置为预定义的静态值,请使用 set() 或 experimental.set()。map():如果使用现有行数据动态设置列值,请使用 map()。
接下来我把上面的Flux脚本修改为set(),发现用时52271515 纳秒 = 0.052272 秒,相对于0.400919s快了0.35s
在这里插入图片描述

5,平衡数据的时间范围和数据精度

官网:

To ensure queries are performant, balance the time range and the precision of your data. For example, if you query data stored every second and request six months worth of data, results would include ≈15.5 million points per series. Depending on the number of series returned after filter()(cardinality), this can quickly become many billions of points. Flux must store these points in memory to generate a response. Use pushdowns to optimize how many points are stored in memory.
To query data over large periods of time, create a task to downsample data, and then query the downsampled data instead.

想要保证查询的性能良好,应该平衡好查询的时间范围和数据精度。如果,有一个 measurement 的数据每秒入库一条,你一次请求 6 个月的数据,那么一个序列就能包含 1550 万点数据。如果序列数再多一些,那么数据很可能会变成数十亿点。Flux 必须将这些 数据拉到内存再返回给用户。所以一方面做好谓词下推尽量减少对内存的使用。另外,如果必须要查询很长时间范围的数据,那应该创建一个定时任务来对数据进行降采样,然后 将查询目标从原始数据改为降采样数据。
在窗口函数优化那一节我们也已经说过,关于降采样的问题,这里就不再赘述了,降采样可以处理时间精度的问题,那么我们再来说一下数据精度
我来区分不通tag查看执行时间
1: 两个filter()->9457596 纳秒 = 0.0094576
在这里插入图片描述

2: 三个filter()-380620 纳秒 = 0.00038062 秒
在这里插入图片描述

我们可以看到随着filter()不断过滤,查询速度也越来越快
为了更好的理解Influx脚本,我们可以看看下面这站图
在这里插入图片描述

我们从源头把水抽取出来,然后按照我们的用水需求,在管道上进行一系列的处理修改(去除沉积物,净化)等,最终以消耗品的方式输送到我们的目的地,这个就可以解释我们的filter就相当于过滤系统,水流越少,执行的速度就越快,所以我们在工作中尽可能的精确的指定filed

未完待续。。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

力扣(LeetCode)382. 链表随机节点(2023.01.15)

给你一个单链表,随机选择链表的一个节点,并返回相应的节点值。每个节点 被选中的概率一样 。 实现 Solution 类: Solution(ListNode head) 使用整数数组初始化对象。 int getRandom() 从链表中随机选择一个节点并返回该节点的值。链表中所有…

WhatsApp居然有3个版本?深度详解区别!外贸圈获客神器用起来!

近两年,外贸圈用WhatsApp来营销获客,越来越火。不少走在前头的外贸人,已经尝到了甜头。但也有不少后来者,站在门外张望的时候,整个人都是蒙圈的。❓听说动不动要整几十个账号,还要花老长时间养号&#xff1…

《Linux Shell脚本攻略》学习笔记-第六章

6.1 简介 你开发应用程序的时间越长,就越能体会到有一个能够跟踪程序修订历史的软件是多重要。 大多数Linux发行版中都包含了Git。如果你的系统中还没有安装,可以通过yum或者apt-get获取。 6.2 创建新的git仓库 git中的所有项目都需要有一个用于保存项目…

MyBatis-Plus字段加密解密

项目创建POM依赖 <dependency><!--MyBatis-Plus 企业级模块--><groupId>com.baomidou</groupId><artifactId>mybatis-mate-starter</artifactId><version>1.2.8</version> </dependency> <!-- https://mvnrepository…

规划之路:SLAM学习经验分享

针对想学SLAM的提问&#xff0c;我觉得我还是有一定的发言权。作为一个刚入坑SLAM一年多的初学者&#xff0c;首先想说的就是这个研究方向比较广&#xff0c;大方向按搭载传感器分为激光SLAM和视觉SLAM两种&#xff0c;激光SLAM搭载激光雷达&#xff0c;视觉SLAM搭载单目、双目…

[NSSRound#6 Team]Web学习

[NSSRound#6 Team]Web学习 文章目录[NSSRound#6 Team]Web学习前言一、[NSSRound#6 Team]check(V1)二、[NSSRound#6 Team]check(Revenge)总结前言 日常做点题娱乐下&#xff0c;刷到了[NSSRound#6 Team]中是三道web题&#xff0c;学习到了不少&#xff0c;记录下知识点。 提示&…

C语言综合练习6:制作贪吃蛇

1 初始化界面 因为还没学QT&#xff0c;我们就使用终端界面替代。 这里我们假设界面中没有障碍物&#xff0c;我们只需要设定界面的高宽就行&#xff0c;这是蛇的移动范围&#xff0c;我们可以写两个宏来规定界面的高宽 新建一个snake.c的文件 #define _CRT_SECURE_NO_WARNIN…

快出数量级的性能是怎样炼成的

前言&#xff1a;今天学长跟大家讲讲《快出数量级的性能是怎样炼成的》&#xff0c;废话不多说&#xff0c;直接上干货~我们之前做过一些性能优化的案例&#xff0c;不算很多&#xff0c;还没有失手过。少则提速数倍&#xff0c;多则数十倍&#xff0c;极端情况还有提速上千倍的…

关于IDEA配置本地tomcat部署项目找不到项目工件的问题解答

文章目录一 原因分析二 解决方案三 具体的操作方法3.1 打开项目结构找到工件3.2 添加具体的工件内容3.3 配置本地tomcat一 原因分析 可能是之前的项目再次打开后&#xff0c;没有及时配置项目结构中的工件信息&#xff0c;导致配置tomcat中看不到工件的信息 二 解决方案 解决…

react组件优化,当父组件数据变化与子组件无关时,控制子组件不重新渲染

首先 我们来建立一个场景 我们创建一个react项目 然后创建一个父组件 这里我要叫 record.jsx 参考代码如下 import React from "react"; import Subset from "./subset";export default class record extends React.Component{constructor(props){super(…

工作的同时,我也在这里做副业

文章目录一、什么是独自开&#xff1f;二、独自开能给我们带来什么利益&#xff1f;三、如何使用独自开&#xff1f;3.1、用户任务报价步骤13.2、用户任务报价步骤2四、未来的愿景一、什么是独自开&#xff1f; 独自开&#xff0c;全称独自开发一套系统&#xff0c;是基于商品…

CTP开发(2)行情模块的开发

我在做CTP开发之前&#xff0c;也参考了不少其他的资料&#xff0c;发现他们都是把行情和交易做在同一个工程里的。我呢之前也做过期货相关的交易平台&#xff0c;感觉这种把行情和交易做在一起的方法缺乏可扩展性。比如我开了多个CTP账户&#xff0c;要同时交易&#xff0c;这…

springMVC的学习拦截器之验证用户登录案例

文章目录实现思路关于环境和配置文件pomspring的配置文件关于idea的通病/常见500错误的避坑实现步骤编写登陆页面编写Controller处理请求编写登录成功的页面编写登录拦截器实现思路 有一个登录页面&#xff0c;需要写一个controller访问页面登陆页面提供填写用户名和密码的表单…

UE4c++日记1(允许 创类、蓝图读写/调用/只读、分类、输出日志打印语句)

目录 1允许创建基于xx的蓝图类 2允许蓝图读写/允许蓝图调用/只读 读写调用 只读 3为变量/函数分类 4输出日志打印一段话 1.先创建一个蓝图类 2.构建对象 3.写提示代码&#xff0c;生成解决方案 4.运行&#xff0c;打开“输出日志” 5.总结 创类-实例化对象&#xff08;构建…

2022年个人年终总结(一)

2022年个人年终总结&#xff08;一&#xff09;考研想法的萌生回顾过去一年-考研心路历程基础阶段&#xff08;1-6月&#xff09;强化阶段&#xff08;7-9月&#xff09;冲刺阶段&#xff08;10-12月&#xff09;感受总结特别感谢2022年是做梦的一年&#xff0c;花了一年的时间…

Zookeeper相关操作

Zookeeper概念 •Zookeeper 是 Apache Hadoop 项目下的一个子项目&#xff0c;是一个树形目录服务。 •Zookeeper 翻译过来就是 动物园管理员&#xff0c;他是用来管 Hadoop&#xff08;大象&#xff09;、Hive(蜜蜂)、Pig(小 猪)的管理员。简称zk •Zookeeper 是一个分布式的…

【C++】非递归实现二叉树的前中后序遍历

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《吃透西嘎嘎》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;二叉树的…

如何运营个人技术博客

前言 本篇和大家聊聊如何运营个人技术博客&#xff0c;定位下做技术写作的目的&#xff0c;有哪些交流平台和输出方式&#xff0c;如何把控内容质量&#xff0c;整理了一些写作技巧和自己常用的写作工具&#xff0c;最后分享下如何在有限的时间里合理安排保证写作与工作的平衡。…

第九届蓝桥杯省赛 C++ A组 - 付账问题

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 &#x1f4da;专栏地址&#xff1a;蓝桥杯题解集合 &#x1f4dd;原题地址&#xff1a;付账问题 &#x1f4e3;专栏定位&#xff1a;为想考甲级PAT的小伙伴整理常考算法题解&#xff0c;祝大家…

理解CSS

CSS 作为前端技术栈中关键一环&#xff0c;对页面元素及样式呈现起到了直接作用。本节课旨在通过对 CSS 的工作流程及原理、页面中 CSS 使用方法等详细解读&#xff0c;帮助前端新手建立对 CSS 的全面而深刻的认知。 CSS概念 CSS 即 Cascading Style Sheets&#xff0c;是用来…