PgSQL-并行查询系列-介绍[译]
PgSQL-并行查询系列-介绍
现代CPU模型拥有大量的CPU核心。多年来,数据库应用程序都是并发向数据库发送查询的。查询处理多个表的行时,若可以使用多核,则可以客观地提升性能。PgSQL 9.6引入了并行查询的新特性,开启并行查询后可以大幅提升性能。
1、局限性
1)若所有CPU核心已经饱和,则不要启动并行查询。并行执行会从其他查询中窃取CPU时间,并增加响应时间
2)进一步需要注意:并行处理会显著增加内存使用(需要注意work_mem的值)。因为,每个hash join或者排序操作都会使用work_mem大小的内存。
3)低延迟的OLTP查询并不能通过并行显著提升性能。特别是仅返回1行的查询,若启用并行,性能会变得特烂。
4)并行执行仅支持没有锁谓词的SELECT查询
5)不支持cursor和会挂起的查询
6)windowed 函数和ordered-set聚合函数都不是并行的
7)对于负载已达IO瓶颈的,并没有啥好处
8)没有并行排序算法。然而,排序查询在某些方面仍然可以并行
9)将CTE(WITH...)替换为sub-select以支持并行执行
10)FDW还不支持并行(后面版本可以,注意哪个版本支持)
11)full outer join不支持
12)客户端设置了max_rows,禁止并行执行
13)如果查询中使用了没有标记为PARALLEL SAFE的函数,那他就是单线程执行
14)SERIALIZABLE事务隔离级别禁用并行执行
2、并行顺序扫描
并行顺序扫描很快,原因可能不是并行读,而是将数据访问分散到多个CPU上。现代操作系统给PgSQL的数据文件提供了很好的缓冲机制。预取允许从存储中获取一个块,而不仅是PgSQL请求的块。因此查询性能限制往往不在IO上,它消耗CPU周期:从表数据页中逐行读取;比较行值和WHERE条件
我们执行一个简单查询:
tpch=# explain analyze select l_quantity as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Seq Scan on lineitem (cost=0.00..1964772.00 rows=58856235 width=5) (actual time=0.014..16951.669 rows=58839715 loops=1)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 1146337
Planning Time: 0.203 ms
Execution Time: 19035.100 ms
一个顺序扫描,没有聚合,需要产生大量行。因此该查询被一个CPU核心执行。添加聚合SUM()后,可以清晰的看到有2个进程帮助查询:
explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1589702.14..1589702.15 rows=1 width=32) (actual time=8553.365..8553.365 rows=1 loops=1)
-> Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)
-> Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 382112
Planning Time: 0.241 ms
Execution Time: 8555.131 ms
性能提升2.2倍。
3、并行聚合
“Parallel Seq Scan”节点为partial aggregation提供行。“Partial Aggregate”节点先对SUM()进行一次操作。最后“Gather”节点汇总每个进程的SUM值。“Finalize Aggregate”节点进行最后计算。如果你使用了聚合函数,不要忘记标记他们为“parallel safe”。
4、进程个数
可以不重启服务,增加并行进程个数:
alter system set max_parallel_workers_per_gather=4;
select * from pg_reload_conf();
Now, there are 4 workers in explain output:
tpch=# explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1440213.58..1440213.59 rows=1 width=32) (actual time=5152.072..5152.072 rows=1 loops=1)
-> Gather (cost=1440213.15..1440213.56 rows=4 width=32) (actual time=5151.807..5153.900 rows=5 loops=1)
Workers Planned: 4
Workers Launched: 4
-> Partial Aggregate (cost=1439213.15..1439213.16 rows=1 width=32) (actual time=5147.238..5147.239 rows=1 loops=5)
-> Parallel Seq Scan on lineitem (cost=0.00..1402428.00 rows=14714059 width=5) (actual time=0.037..3601.882 rows=11767943 loops=5)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 229267
Planning Time: 0.218 ms
Execution Time: 5153.967 ms
我们将并发进程由2改成了4,但是查询仅快1.6599倍。实际上,我们有2个进程+一个leader,配置改好成为4+1。并行最大提升可以:5/3=1.66倍。
5、如何工作?
查询执行总是从“leader”进程开始。Leader进程执行所有非并行动作。其他进程执行相同查询,称为“worker”进程。并行利用Dynamic Backgroud workers基础架构(9.4引入)执行。因此创建3个工作进程的查询可能比传统执行快4倍。
Worker进程使用消息队列(基于共享内存)和leader进行通信。每个进程有2个队列:一个为errors,另一个是tuples。
5、进程使用个数
1)max_parallel_workers_per_gather是workers进程数的最小限制
2)查询执行使用的workers限制为max_parallel_workes
3)最上层的限制是max_worker_processes:后台进程的总数
分配进程失败,会导致使用单进程执行。查询规划器会根据表或索引大小来增加worker个数。min_parallel_table_scan_size和min_parallel_index_scan_size控制该行为。
set min_parallel_table_scan_size='8MB'
8MB table => 1 worker
24MB table => 2 workers
72MB table => 3 workers
x => log(x / min_parallel_table_scan_size) / log(3) + 1 worker
表比min_parallel_(index|table)_scan_size值每大3倍,PG增加一个worker进程。Workers进程个数不是基于成本的。循环依赖使得复杂的实现变得困难。相反,规划者使用简单的规则。
可以通过ALTER TABLE … SET (parallel_workers = N)来对某个表指定并行进程数。
6、为什么不使用并行
除了并行限制外,PG还会检查代价:
parallel_setup_cost:避免短查询的并行执行。模拟用于内存设置、流程启动和初始通信的时间
parallel_tuple_cost:leader和worker之间通信可能花费很长时间。时间和worker发送的记录数成正比。参数对通信成本进行建模。
7、Nested Loop Join
PgSQL9.6+可以以并行形式执行“Nested loop”。
explain (costs off) select c_custkey, count(o_orderkey)from customer left outer join orders onc_custkey = o_custkey and o_comment not like '%special%deposits%'group by c_custkey;QUERY PLAN
--------------------------------------------------------------------------------------Finalize GroupAggregateGroup Key: customer.c_custkey-> Gather MergeWorkers Planned: 4-> Partial GroupAggregateGroup Key: customer.c_custkey-> Nested Loop Left Join-> Parallel Index Only Scan using customer_pkey on customer-> Index Scan using idx_orders_custkey on ordersIndex Cond: (customer.c_custkey = o_custkey)Filter: ((o_comment)::text !~~ '%special%deposits%'::text)
Gather发生在最后阶段,因此“Nested Loop Left Join”是并行操作。“Parallel Index Only Scan”在版本10才可以使用,和并行顺序扫描类似。c_custkey = o_custkey条件读取每个customer行的order列,因此不是并行。
8、Hash Join
PgSQL11中每个worker构建自己的hash table。因此,4+ workers不能提升性能。新的实现方式:使用一个共享hash table。每个worker可以利用WORK_MEM来构建hash table>
selectl_shipmode,sum(casewhen o_orderpriority = '1-URGENT'or o_orderpriority = '2-HIGH'then 1else 0end) as high_line_count,sum(casewhen o_orderpriority <> '1-URGENT'and o_orderpriority <> '2-HIGH'then 1else 0end) as low_line_count
fromorders,lineitem
whereo_orderkey = l_orderkeyand l_shipmode in ('MAIL', 'AIR')and l_commitdate < l_receiptdateand l_shipdate < l_commitdateand l_receiptdate >= date '1996-01-01'and l_receiptdate < date '1996-01-01' + interval '1' year
group byl_shipmode
order byl_shipmode
LIMIT 1;QUERY PLAN -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Limit (cost=1964755.66..1964961.44 rows=1 width=27) (actual time=7579.592..7922.997 rows=1 loops=1)-> Finalize GroupAggregate (cost=1964755.66..1966196.11 rows=7 width=27) (actual time=7579.590..7579.591 rows=1 loops=1)Group Key: lineitem.l_shipmode-> Gather Merge (cost=1964755.66..1966195.83 rows=28 width=27) (actual time=7559.593..7922.319 rows=6 loops=1)Workers Planned: 4Workers Launched: 4-> Partial GroupAggregate (cost=1963755.61..1965192.44 rows=7 width=27) (actual time=7548.103..7564.592 rows=2 loops=5)Group Key: lineitem.l_shipmode-> Sort (cost=1963755.61..1963935.20 rows=71838 width=27) (actual time=7530.280..7539.688 rows=62519 loops=5)Sort Key: lineitem.l_shipmodeSort Method: external merge Disk: 2304kBWorker 0: Sort Method: external merge Disk: 2064kBWorker 1: Sort Method: external merge Disk: 2384kBWorker 2: Sort Method: external merge Disk: 2264kBWorker 3: Sort Method: external merge Disk: 2336kB-> Parallel Hash Join (cost=382571.01..1957960.99 rows=71838 width=27) (actual time=7036.917..7499.692 rows=62519 loops=5)Hash Cond: (lineitem.l_orderkey = orders.o_orderkey)-> Parallel Seq Scan on lineitem (cost=0.00..1552386.40 rows=71838 width=19) (actual time=0.583..4901.063 rows=62519 loops=5)Filter: ((l_shipmode = ANY ('{MAIL,AIR}'::bpchar[])) AND (l_commitdate < l_receiptdate) AND (l_shipdate < l_commitdate) AND (l_receiptdate >= '1996-01-01'::date) AND (l_receiptdate < '1997-01-01 00:00:00'::timestamp without time zone))Rows Removed by Filter: 11934691-> Parallel Hash (cost=313722.45..313722.45 rows=3750045 width=20) (actual time=2011.518..2011.518 rows=3000000 loops=5)Buckets: 65536 Batches: 256 Memory Usage: 3840kB-> Parallel Seq Scan on orders (cost=0.00..313722.45 rows=3750045 width=20) (actual time=0.029..995.948 rows=3000000 loops=5)Planning Time: 0.977 msExecution Time: 7923.770 ms
TPC-H中的SQL12是并行hash join的一个很好的哪里,每个进程都帮助构建共享hash table。
9、Merge Join
由于merge join的特性,使得不能并行。如果merge join是查询执行的最后阶段,那么不用担心,仍可以使用并行。
-- Query 2 from TPC-H
explain (costs off) select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment
from part, supplier, partsupp, nation, region
wherep_partkey = ps_partkeyand s_suppkey = ps_suppkeyand p_size = 36and p_type like '%BRASS'and s_nationkey = n_nationkeyand n_regionkey = r_regionkeyand r_name = 'AMERICA'and ps_supplycost = (selectmin(ps_supplycost)from partsupp, supplier, nation, regionwherep_partkey = ps_partkeyand s_suppkey = ps_suppkeyand s_nationkey = n_nationkeyand n_regionkey = r_regionkeyand r_name = 'AMERICA')
order by s_acctbal desc, n_name, s_name, p_partkey
LIMIT 100;QUERY PLAN
----------------------------------------------------------------------------------------------------------Limit-> SortSort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name, part.p_partkey-> Merge JoinMerge Cond: (part.p_partkey = partsupp.ps_partkey)Join Filter: (partsupp.ps_supplycost = (SubPlan 1))-> Gather MergeWorkers Planned: 4-> Parallel Index Scan using <strong>part_pkey</strong> on partFilter: (((p_type)::text ~~ '%BRASS'::text) AND (p_size = 36))-> Materialize-> SortSort Key: partsupp.ps_partkey-> Nested Loop-> Nested LoopJoin Filter: (nation.n_regionkey = region.r_regionkey)-> Seq Scan on regionFilter: (r_name = 'AMERICA'::bpchar)-> Hash JoinHash Cond: (supplier.s_nationkey = nation.n_nationkey)-> Seq Scan on supplier-> Hash-> Seq Scan on nation-> Index Scan using idx_partsupp_suppkey on partsuppIndex Cond: (ps_suppkey = supplier.s_suppkey)SubPlan 1-> Aggregate-> Nested LoopJoin Filter: (nation_1.n_regionkey = region_1.r_regionkey)-> Seq Scan on region region_1Filter: (r_name = 'AMERICA'::bpchar)-> Nested Loop-> Nested Loop-> Index Scan using idx_partsupp_partkey on partsupp partsupp_1Index Cond: (part.p_partkey = ps_partkey)-> Index Scan using supplier_pkey on supplier supplier_1Index Cond: (s_suppkey = partsupp_1.ps_suppkey)-> Index Scan using nation_pkey on nation nation_1Index Cond: (n_nationkey = supplier_1.s_nationkey)
“Merge Join”节点在“Gather Merge”上。因此merge不使用并行。但是“Parallel Index Scan”仍旧有助于part_pkey。
10、Partition-wise join
PgSQL11默认禁止partition-wise join特性。它有一个很高的规划代价。分区表可以一个分区一个分区的进行join。允许使用更小的hash table。每个per-partition join操作可以并行:
tpch=# set enable_partitionwise_join=t;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;QUERY PLAN
---------------------------------------------------Append-> Hash JoinHash Cond: (t2.b = t1.a)-> Seq Scan on prt2_p1 t2Filter: ((b >= 0) AND (b <= 10000))-> Hash-> Seq Scan on prt1_p1 t1Filter: (b = 0)-> Hash JoinHash Cond: (t2_1.b = t1_1.a)-> Seq Scan on prt2_p2 t2_1Filter: ((b >= 0) AND (b <= 10000))-> Hash-> Seq Scan on prt1_p2 t1_1Filter: (b = 0)
tpch=# set parallel_setup_cost = 1;
tpch=# set parallel_tuple_cost = 0.01;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;QUERY PLAN
-----------------------------------------------------------GatherWorkers Planned: 4-> Parallel Append-> Parallel Hash JoinHash Cond: (t2_1.b = t1_1.a)-> Parallel Seq Scan on prt2_p2 t2_1Filter: ((b >= 0) AND (b <= 10000))-> Parallel Hash-> Parallel Seq Scan on prt1_p2 t1_1Filter: (b = 0)-> Parallel Hash JoinHash Cond: (t2.b = t1.a)-> Parallel Seq Scan on prt2_p1 t2Filter: ((b >= 0) AND (b <= 10000))-> Parallel Hash-> Parallel Seq Scan on prt1_p1 t1Filter: (b = 0)
分区连接只有在分区足够大的情况下才能使用并行执行
11、Parallel Append
Parallel Append通常在UNION ALL中。缺点:较小的并行度,因为每个worker进程最终都为一个查询服务。即使启用了4个进程,也会仍旧发起2个:
tpch=# explain (costs off) select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day union all select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '2000-12-01' - interval '105' day;QUERY PLAN
------------------------------------------------------------------------------------------------GatherWorkers Planned: 2-> Parallel Append-> Aggregate-> Seq Scan on lineitemFilter: (l_shipdate <= '2000-08-18 00:00:00'::timestamp without time zone)-> Aggregate-> Seq Scan on lineitem lineitem_1Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
12、更重要的变量
WORKER_MEM:限制每个进程的使用内存。每个查询:work_mem*processes*joins-->会导致内存使用很大
max_parallel_workers_per_gather:执行器使用多少进程并发执行该节点
max_worker_processes:根据服务器上CPU核数调整进程数
max_parallel_workers:和并发进程数一样
13、总结
从9.6并行查询执行开始,可以显著提高扫描许多行或索引记录的复杂查询的性能。不要忘记在高oltp工作负载的服务器上禁止并行执行。顺序扫描或索引扫描仍然耗费大量资源。如果您没有针对整个数据集运行报表,那么只需添加缺失的索引或使用适当的分区就可以提高查询性能。
原文
https://www.percona.com/blog/parallel-queries-in-postgresql/
相关文章:
PgSQL-并行查询系列-介绍[译]
PgSQL-并行查询系列-介绍 现代CPU模型拥有大量的CPU核心。多年来,数据库应用程序都是并发向数据库发送查询的。查询处理多个表的行时,若可以使用多核,则可以客观地提升性能。PgSQL 9.6引入了并行查询的新特性,开启并行查询后可以大…...

Linux以系统服务的方式启动Kafka(其他服务同理)
最终效果: 先回顾命令行的启动方式: kafka的启动 进入kafka的安装目录 1、首先启动zookeeper服务: bin/zookeeper-server-start.sh config/zookeeper.properties2、再启动kafka bin/kafka-server-start.sh config/server.properties &…...

成都瀚网科技有限公司:抖店的评论会消失吗?
抖店是抖音推出的电子商务平台。很多用户在购物后都会对产品进行评价。但有时用户可能会发现抖店评论缺失,让用户产生一些疑惑和困惑。本文将围绕这个问题提供一些答案和解决方案。 1.为什么抖店评论不见了? 首先需要明确的是,抖店评论消失可…...

优先级队列priority_queue以及仿函数的使用
目录 优先级队列priority_queuepriority_queue的模拟实现仿函数 优先级队列priority_queue 优先级队列priority_queue是一种容器适配器,根据严格的弱排序标准,它默认第一个元素总是它所包含的元素中最大的 优先级队列默认使用vector作为底层存储数据的…...

java+ssm+mysql水费管理系统
项目介绍: 使用javassmmysql开发的用户水费管理系统,系统包含超级管理员,系统管理员、用户角色,功能如下: 超级管理员:管理员管理、用户管理、用水管理(用水记录、缴费提醒)、水费…...

搭建最简单的SpringBoot项目
1、创建maven项目 2、引入父pom <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.15</version> </parent> 3、引入springboot-web依赖 <dependency…...
Windows系统手动重新生成性能计数器
症状 使用性能监视器工具时,某些计数器可能缺失或不包含计数器数据。 性能计数器库可能已损坏,需要重新生成。 应用程序日志中可能会出现以下错误: Log Name: Application Source: Microsoft-Windows-IIS-W3SVC-PerfCounters Event ID…...
go elsaticsearch demo
安装 // elasticsearch sdk go get -u github.com/elastic/go-elasticsearch/v7 //操作json go get "github.com/tidwall/gjson" go get "github.com/aquasecurity/esquery"demo package esexampleimport ("bytes""context""en…...

小游戏分发平台如何以技术拓流?
2023年,小游戏的发展将受到多方面的影响,例如新技术的引入、参与小游戏的新玩家以及游戏市场的激烈竞争等。首先,新技术如虚拟现实(VR)、增强现实(AR)和机器人技术都可以带来新颖的游戏体验。其…...

力扣|找出和所对应的两数的下标
从零开始刷力扣(bushi 题目放在这: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值target的两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一…...

使用命令行创建仓库
如果你还没有任何代码,可以通过命令行工具创建一个全新的Git仓库并初始化到本项目仓库中。 git clone https://e.coding.net/***/neurosens.git cd neurosens echo "# neurosens" >> README.md git add README.md git commit -m "first commi…...

ESLint 中的“ space-before-function-paren ”相关报错及其解决方案
ESLint 中的“ space-before-function-paren ”相关报错及其解决方案 出现的问题及其报错: 在 VScode 中,在使用带有 ESLint 工具的项目中,保存会发现报错,并且修改好代码格式后,保存会发现代码格式依然出现问题&…...

docker常用中间件安装
文章目录 1、前言2、中间件安装2.1、mysql2.2、gitlab容器2.3、nacos2.4、redis2.5、xxljob2.6、zipkin2.7、sentinel2.8、seata2.8.1、获取镜像2.8.2、运行容器并获取配置 2.9、rockerMQ2.9.1、rockerMQ-namesrv2.9.2、rockerMQ-broker2.9.3、rockerMQ-console 2.10、jenkins2…...
Camunda 7.x 系列【44】修改流程实例
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 概述2. 案例演示2.1 回退2.2 子流程2.3 多实例加签1. 概述 流程模型中,执行活动需要按…...

无频闪护眼灯哪个好?什么是无频闪
随着科技的不断发展,工作时使用电子设备越来越普遍,如何保护我们的眼睛不受蓝光、频闪等危害就变得极其重要了。护眼台灯,顾名思义就是保护眼睛的台灯,其工作原理是在光源处使用特殊的防蓝光灯珠,并通过控制电流的稳定性来达到防频…...

css网格布局
css网格布局 常用属性 display: grid; //开启网格grid-template-columns: 2fr 1fr 1fr 1fr 1fr; //设置多少列每列宽度grid-gap: 10px; // 设置表格之间间距grid-template-rows: 50px 50px 50px 50px; // 设置多少行 每行的高度grid-column : 1 //占据位置 占据1格grid-colu…...
Hadoop -HDFS常用操作指令
1.启动HDFS hadoop/sbin/start-dfs.sh2.关闭 HDFS hadoop/sbin/stop-dfs.sh3. 在HDFS中创建文件夹 #老版本 hadoop fs -mkdir -p path #新版本 hadoop dfs -mkdir -p path4.查看指定目录下内容 hadoop fs -ls [-h] [-R] path hadoop dfs -ls [-h] [-R] ptahpath 指定…...
代码随想录二刷day11
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣20. 有效的括号二、力扣1047. 删除字符串中的所有相邻重复项三、力扣150. 逆波兰表达式求值 前言 一、力扣20. 有效的括号 class Solution {public bo…...

系统架构技能之设计模式-工厂模式
一、开篇 本文主要是讲述设计模式中最经典的创建型模式-工厂模式,本文将会从以下几点对工厂模式进行阐述。 本文将会从上面的四个方面进行详细的讲解和说明,当然会的朋友可以之处我的不足之处,不会的朋友也请我们能够相互学习讨论。 二、摘…...

Docker的基本组成和安装
Docker的基本组成 镜像(image): docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像 > run > tomcat01容器(提供服务) 通过这个镜像可以创建多个容器(最…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...