当前位置: 首页 > news >正文

如何设置并行度 ——《OceanBase 并行执行》系列 2

并行度(degree of parallelism,简称 DOP),是指在执行过程中所使用的工作线程数量。设计并行执行的初衷在于充分利用多核资源以提升效率。OceanBase 的并行执行框架支持多种设定并行度的方式,既允许用户手动设置,也提供了  Auto DOP 的功能使系统能为用户自动选择合适的并行度。
本篇将重点阐述如何手动设置并行度。

并行执行系列的内容分为七篇博客,本篇是其中的第二篇。

第一篇并行执行概念

2.1 手工指定并行度

可以对一张表指定并行度,使得对这张表的扫描总是使用并行执行。

2.1.1 指定并行度的几种方式

表属性指定并行度

下面的语句分别指定一张主表和一个索引的扫描并行度。

ALTER TABLE table_name PARALLEL 4;
ALTER TABLE table_name ALTER INDEX index_name PARALLEL 2;

如果一个 SQL 中只涉及一张表,当 SQL 中查询了主表时,除了主表所在的 DFO,其余 DFO 也会使用并行度 4 来执行;当 SQL 查询了索引表时,除了索引表所在的 DFO,其余 DFO 也会使用并行度 2 来执行。

如果一个 SQL 中涉及多张表,则会使用 PARALLEL 最大值作为整个计划的 DOP。

PARALLEL HINT 指定并行度

可以通过全局 PARALLEL HINT 来指定整个 SQL 的并行度,也可以通过表级的 PARALLEL HINT 来指定特定表的并行度。当一个 SQL 里给定了多个表的 PARALLEL HINT,那么各个表所在 DFO 的 DOP 由各个表的 Parallel 值决定。如果一个 DFO 里包含多张表,则会取他们的 PARALLEL 最大值作为 DFO 的 DOP。 

OceanBase(TEST@TEST)>create table t1 (c1 int, c2 int);
Query OK, 0 rows affected (0.167 sec)OceanBase(TEST@TEST)>explain select /*+ parallel(3) */ sum(c1) from t1;
+----------------------------------------------------------------------+
| Query Plan                                                           |
+----------------------------------------------------------------------+
| =========================================================            |
| |ID|OPERATOR             |NAME    |EST.ROWS|EST.TIME(us)|            |
| ---------------------------------------------------------            |
| |0 |SCALAR GROUP BY      |        |1       |2           |            |
| |1 | PX COORDINATOR      |        |3       |2           |            |
| |2 |  EXCHANGE OUT DISTR |:EX10000|3       |2           |            |
| |3 |   MERGE GROUP BY    |        |3       |1           |            |
| |4 |    PX BLOCK ITERATOR|        |1       |1           |            |
| |5 |     TABLE SCAN      |T1      |1       |1           |            |
| =========================================================            |
| Outputs & filters:                                                   |
| -------------------------------------                                |
|   0 - output([T_FUN_SUM(T_FUN_SUM(T1.C1))]), filter(nil), rowset=256 |
|       group(nil), agg_func([T_FUN_SUM(T_FUN_SUM(T1.C1))])            |
|   1 - output([T_FUN_SUM(T1.C1)]), filter(nil), rowset=256            |
|   2 - output([T_FUN_SUM(T1.C1)]), filter(nil), rowset=256            |
|       dop=3                                                          |
|   3 - output([T_FUN_SUM(T1.C1)]), filter(nil), rowset=256            |
|       group(nil), agg_func([T_FUN_SUM(T1.C1)])                       |
|   4 - output([T1.C1]), filter(nil), rowset=256                       |
|   5 - output([T1.C1]), filter(nil), rowset=256                       |
|       access([T1.C1]), partitions(p0)                                |
|       is_index_back=false, is_global_index=false,                    |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true    |
+----------------------------------------------------------------------+
24 rows in set (0.002 sec)
OceanBase(TEST@TEST)>create table t1 (c1 int, c2 int);
Query OK, 0 rows affected (0.167 sec)OceanBase(TEST@TEST)>create table t2 (c1 int, c2 int);
Query OK, 0 rows affected (0.150 sec)OceanBase(TEST@TEST)>select /*+ parallel(t1 3) */ * from t1, t2 where t1.c2 = t2.c1;
Empty set (0.041 sec)OceanBase(TEST@TEST)>explain select /*+ parallel(t1 3) */ * from t1, t2 where t1.c2 = t2.c1;
+----------------------------------------------------------------------------------------+
| Query Plan                                                                             |
+----------------------------------------------------------------------------------------+
| =================================================================                      |
| |ID|OPERATOR                     |NAME    |EST.ROWS|EST.TIME(us)|                      |
| -----------------------------------------------------------------                      |
| |0 |PX COORDINATOR               |        |1       |7           |                      |
| |1 | EXCHANGE OUT DISTR          |:EX10002|1       |6           |                      |
| |2 |  HASH JOIN                  |        |1       |5           |                      |
| |3 |   EXCHANGE IN DISTR         |        |1       |2           |                      |
| |4 |    EXCHANGE OUT DISTR (HASH)|:EX10000|1       |2           |                      |
| |5 |     PX BLOCK ITERATOR       |        |1       |1           |                      |
| |6 |      TABLE SCAN             |T1      |1       |1           |                      |
| |7 |   EXCHANGE IN DISTR         |        |1       |4           |                      |
| |8 |    EXCHANGE OUT DISTR (HASH)|:EX10001|1       |4           |                      |
| |9 |     PX PARTITION ITERATOR   |        |1       |2           |                      |
| |10|      TABLE SCAN             |T2      |1       |2           |                      |
| =================================================================                      |
| Outputs & filters:                                                                     |
| -------------------------------------                                                  |
|   0 - output([INTERNAL_FUNCTION(T1.C1, T1.C2, T2.C1, T2.C2)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1, T1.C2, T2.C1, T2.C2)]), filter(nil), rowset=256 |
|       dop=3                                                                            |
|   2 - output([T1.C2], [T2.C1], [T1.C1], [T2.C2]), filter(nil), rowset=256              |
|       equal_conds([T1.C2 = T2.C1]), other_conds(nil)                                   |
|   3 - output([T1.C2], [T1.C1]), filter(nil), rowset=256                                |
|   4 - output([T1.C2], [T1.C1]), filter(nil), rowset=256                                |
|       (#keys=1, [T1.C2]), dop=3                                                        |
|   5 - output([T1.C2], [T1.C1]), filter(nil), rowset=256                                |
|   6 - output([T1.C2], [T1.C1]), filter(nil), rowset=256                                |
|       access([T1.C2], [T1.C1]), partitions(p0)                                         |
|       is_index_back=false, is_global_index=false,                                      |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true                      |
|   7 - output([T2.C1], [T2.C2]), filter(nil), rowset=256                                |
|   8 - output([T2.C1], [T2.C2]), filter(nil), rowset=256                                |
|       (#keys=1, [T2.C1]), dop=1                                                        |
|   9 - output([T2.C1], [T2.C2]), filter(nil), rowset=256                                |
|       force partition granule                                                          |
|  10 - output([T2.C1], [T2.C2]), filter(nil), rowset=256                                |
|       access([T2.C1], [T2.C2]), partitions(p0)                                         |
|       is_index_back=false, is_global_index=false,                                      |
|       range_key([T2.__pk_increment]), range(MIN ; MAX)always true                      |
+----------------------------------------------------------------------------------------+
39 rows in set (0.002 sec)

对于 DML 语句,使用上面的 HINT,只会使得 DML 语句的查询部分走并行,写入部分还是串行。如果希望写入部分也并行,则需要还添加一个 HINT ENABLE_PARALLEL_DML,例如:

insert /*+ parallel(3) enable_parallel_dml */ into t3 select * from t1;

注意:并行 DML 必须指定全局 parallel hint。仅指定表级 parallel hint 无法让写入部分串行。例如,下面的 SQL 不会开启 DML 并行:

insert /*+ parallel(t3 3) enable_parallel_dml */ into t3 select * from t1;

SESSION 上指定并行度

在当前 session 上指定并行度后,session 上的所有查询语句都将以这个并行度执行。需要注意,即使是单行查询的 SQL,也会使用该并行度,可能导致性能下降。

set _force_parallel_query_dop = 3

对于 DML 语句,使用上面的命令,只会使得 DML 语句的查询部分走并行,写入部分还是串行。如果希望写入部分也并行,则需要用下面的命令:

set _force_parallel_dml_dop = 3

2.1.2 并行度优先级

全局 HINT > TABLE HINT > SESSION 并行度 > TABLE DOP

对比全局 HINT 和 TABLE HINT 的优先级。可以看到,有全局 HINT 时,TABLE HINT 不生效。

OceanBase(TEST@TEST)>explain select /*+ parallel(2) parallel(t1 3) */ * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |2           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |2           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=2                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)OceanBase(TEST@TEST)>explain select /*+ parallel(t1 3) */ * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |2           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |1           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=3                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)

对比 session 和 table hint 的优先级。可以看到,使用 table 级的 HINT 时,session 设定的 DOP 不生效。

OceanBase(TEST@TEST)>alter session force parallel query parallel 4;
Query OK, 0 rows affected (0.001 sec)OceanBase(TEST@TEST)>explain select /*+ parallel(t1 3) */ * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |2           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |1           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=3                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)OceanBase(TEST@TEST)>explain select * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |1           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |1           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=4                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)

对比 session 和 table parallel 的优先级。可以看到 table parallel 属性的优先级低于 session 指定 dop 的优先级。

OceanBase(TEST@TEST)>alter table t1 parallel 5;
Query OK, 0 rows affected (0.135 sec)OceanBase(TEST@TEST)>explain select * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |1           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |1           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=5                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)OceanBase(TEST@TEST)>alter session force parallel query parallel 4;
Query OK, 0 rows affected (0.000 sec)OceanBase(TEST@TEST)>explain select * from t1;
+-------------------------------------------------------------------+
| Query Plan                                                        |
+-------------------------------------------------------------------+
| =======================================================           |
| |ID|OPERATOR           |NAME    |EST.ROWS|EST.TIME(us)|           |
| -------------------------------------------------------           |
| |0 |PX COORDINATOR     |        |1       |1           |           |
| |1 | EXCHANGE OUT DISTR|:EX10000|1       |1           |           |
| |2 |  PX BLOCK ITERATOR|        |1       |1           |           |
| |3 |   TABLE SCAN      |T1      |1       |1           |           |
| =======================================================           |
| Outputs & filters:                                                |
| -------------------------------------                             |
|   0 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|   1 - output([INTERNAL_FUNCTION(T1.C1)]), filter(nil), rowset=256 |
|       dop=4                                                       |
|   2 - output([T1.C1]), filter(nil), rowset=256                    |
|   3 - output([T1.C1]), filter(nil), rowset=256                    |
|       access([T1.C1]), partitions(p0)                             |
|       is_index_back=false, is_global_index=false,                 |
|       range_key([T1.__pk_increment]), range(MIN ; MAX)always true |
+-------------------------------------------------------------------+
18 rows in set (0.002 sec)

2.1.3 并行度取值

先讲一个简单原则:1. parallel 的设定目的是为了把 CPU 用满。2. parallel 不是越大越好。举个例子:当租户 CPU 为 20 的时:

  • 对于单表简单操作(如单表扫描过滤、单表增删改)parallel 理论值为 20。
  • 对于多表 join 的查询、带全局索引的 PDML,parallel 理论值为 10。
  • 对于一些更加复杂的计划,形态为右深树时,parallel 理论值为 7 左右。

对上面的例子做解释

  • 对于单表操作,只有一个 DFO,可以把 20 个 CPU 全部给这个 DFO 用。
  • 对于多表 join,同一时间会启动 2 个 DFO,形成数据流水线(一个 DFO 是 producer、一个 DFO 是consumer),所有每个 DFO 分 10 个 CPU。
  • 对于更加复杂的右深树计划,我们同一时间会启动 3 个 DFO,此时每个 DFO 大约分 7 个 CPU 可以保证他们都能跑得比较快。

但是,以上只是一般原则,实际操作中还是应该做微调。解释如下:

  • 对于单表操作,只有一个 DFO,可以把 20 个 CPU 全部给这个 DFO 用。
假设这个 DFO 大部分时间是做 IO,那么不妨把并发度设置得比 20 稍高一些,比如 25,这样可以充分利用 CPU
  • 对于多表 join,同一时间会启动 2 个 DFO,形成数据流水线(一个 DFO 是 producer、一个 DFO 是consumer),所有每个 DFO 分 10 个 CPU。
我们实际并不能保证每个 DFO 都能把分给他的 CPU 压满。所以,把并发度适当稍微调整高一些,比如 15 也许能更充分地利用 CPU。 ** 但是,不能无限往上加。把并发度加到 50,根本不会有收益,相反还会增加线程调度开销、框架调度开销。
  • 对于更加复杂的右深树计划,我们同一时间会启动 3 个 DFO,此时每个 DFO 大约分 7 个 CPU 可以保证他们都能跑得比较快。
一个计划里,并不是处处都要启动 3 个 DFO,3 DFO 的情况可能是局部的。大部分时候可能还是同时启动 2 个 DFO。 所以这时候把并发设置为 10 也许比 7 要好。

微调后,当租户 CPU 为 20 的时,一个可能的情况如下:

  • 对于单表简单操作(如单表扫描过滤、单表增删改)parallel 实践值为 30。
  • 对于多表 join 的查询、带全局索引的 PDML,parallel 实践值为 15。
  • 对于一些更加复杂的计划,形态为右深树时,parallel 实践值为 10 ~ 15 左右。

相关文章:

如何设置并行度 ——《OceanBase 并行执行》系列 2

并行度(degree of parallelism,简称 DOP),是指在执行过程中所使用的工作线程数量。设计并行执行的初衷在于充分利用多核资源以提升效率。OceanBase 的并行执行框架支持多种设定并行度的方式,既允许用户手动设置&#x…...

python直接发布到网站wordpress之三批量发布图片

在前面的文章中,实现了使用python操作wordpress发布文字内容和图片内容。 python直接发布到网站wordpress之一只发布文字-CSDN博客 python直接发布到网站wordpress之二发布图片-CSDN博客 不过,此时发布图片的数量只能是一张图片。但在实际应用中&…...

C#面:ADO.NET 相对于ADO等主要有什么改进

C# ADO.NET 是微软为.NET平台开发的一套数据访问技术,相对于传统的ADO(ActiveX Data Objects)等,它有以下几个主要改进: 面向对象:ADO.NET 是面向对象的数据访问技术,它使用.NET框架中的类和对…...

web前端学习笔记7-iconfont使用

7. iconfont的使用流程 字体图标使用较多的是阿里巴巴iconfont图标库,它是阿里巴巴体验团队推出的图标库和图标管理平台,提供了大量免费和可定制的矢量图标,以满足网页设计、平面设计、UI设计、应用程序开发和其他创意项目的需求。 官方网站:https://www.iconfont.cn/ 使用…...

国内小白用什么方法充值使用ChatGPT4.0?

首先说一下IOS礼品卡订阅,目前最经济实惠的订阅方式,具体操作步骤 使用IOS设备充值,用 App Stroe 兑换券 1、支付宝地址切换旧金山,在里面买app store 的兑换卷 2、美区Apple ID登陆app store ,充值兑换券 3、IOS设…...

富格林:正确杜绝欺诈实现出金

富格林悉知,现货黄金一直以来都是投资者们追逐的热门品种之一。其安全性和避险特性吸引着广大投资者。但在现货黄金市场中要想实现出金其实并不简单,是需要我们通过一定的技巧和方法去正确杜绝欺诈套路。下面为了帮助广大投资者正确杜绝欺诈实现出金&…...

基于java,SpringBoot和VUE的求职招聘简历管理系统设计

摘要 基于Java, Spring Boot和Vue的求职招聘管理系统是一个为了简化求职者与雇主间互动流程而设计的现代化在线平台。该系统后端采用Spring Boot框架,以便快速搭建具有自动配置、安全性和事务管理等特性的RESTful API服务,而前端则使用Vue.js框架构建动…...

sqlserver数据库日志文件log.ldf文件占用过大清除的办法

sqlserver数据库日志文件log.ldf文件占用过大清除的办法 技术交流 http://idea.coderyj.com/ 1.清除数据库日志的方法 --- 查看数据库日志文件名 USE cs GO SELECT file_id, name,size,* FROM sys.database_files;ps 可以看到其中name字段为数据库日志名称"数据库日志名称…...

【Python小技巧】matplotlib不显示图像竟是numpy惹的祸

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、问题:df.plot() 显示不出图像二、尝试各种解决办法1. 增加matplotlib.use,设定GUI2. 升级matplotlib版本 三、numpy是个重要的库1. …...

【AIGC】1、爆火的 AIGC 到底是什么 | 全面介绍

文章目录 一、AIGC 的简要介绍二、AIGC 的发展历程三、AIGC 的基石3.1 基本模型3.2 基于人类反馈的强化学习3.3 算力支持 四、生成式 AI(Generative AI)4.1 单模态4.1.1 生成式语言模型(Generative Language Models,GLM&#xff0…...

云计算技术概述_3.云计算的部署方式

根据NIST的定义,云计算从部署模式上看可以分为公有云、社区云、私有云和混合云四种类型。 注:NIST(美国国家标准与技术研究院)是美国商务部下属的一个物理科学实验室和非监管机构。 其任务是促进创新和行业竞争力。 NIST 将其活动…...

简述 BIO 、NIO 模型

BIO : 同步阻塞I/O(Block IO) 服务器实现模式为每一个连接一个线程,即客户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,此处可以通过线程池机制进行优化。 impo…...

【Python小练】随机验证码

题目 提示输出含数字、字母的四位随机数,输入提示的验证码进行验证,验证码正确结束程序,验证码错误继续输入。 分析 我们可以通过random模块生成0到9的随机数,也可以通过生成65到90的随机数,将65到90的随机ASCLL码转换…...

《1w实盘and大盘基金预测 day30》

今日预测: 3123-3150-3177 探底回升,震荡上涨,收小红小绿 双创指数后期上涨的幅度也是会大于上证的,四月底的时候就提醒建仓。 关注板块:医疗、地产、电力、证券 这周预测 这周上证指数最高看到3200 继续看涨&#…...

软件工程案例学习-图书管理系统-面向对象方法

文档编号:LMS_1 版 本 号:V1.0 ** ** ** ** ** ** 文档名称:需求分析规格说明书 项目名称:图书管理系统 项目负责人:计敏 胡杰 ** ** …...

python:机器学习特征优选(过滤法)

作者:CSDN @ _养乐多_ 本文将介绍如何使用 python 语言使用过滤法进行机器学习特征优选。分别有F值、互信息(Mutual Information,MI)、方差阈值(Variance Threshold,VT)、相关性方法。 文章目录 一、特征数据1.1 将用于分析的数据从GEE下载到本地1.2 从其他方法获取二、…...

CH32V 系列 MCU IAP 使用函数形式通过传参形式灵活指定APP跳转地址

参考: CH32V 系列 MCU IAP 升级跳转方法 CH32V103 的 IAP 问题(跳转及中断向量表重定位) 1. 沁恒的RISC-V内核MCU的IAP跳转示例程序简要分析 沁恒的RISC-V内核的MCU比如CH32V203、CH32V307等系列的EVT包中IAP升级的示例程序中都是通过使能软件中断之后&…...

教程分享:如何为跨境电商、外贸、国际展会制作二维码?

不论是做跨境电商、在全球做产品推广,还是国外的餐厅运营、参加国际展会,或者是做创意户外广告、制作个性化的个人名片、有趣的产品包装……只要是在国外使用二维码,你都可以在QR Tiger去制作您需要的二维码! 一、认识QR Tiger 二…...

ComfyUI 基础教程(十三):ComfyUI-Impact-Pack 面部修复

SD的WebUI 中的面部修复神器 ADetailer,无法在ComfyUI 中使用。那么如何在ComfyUI中进行面部处理呢?ComfyUI 中也有几个面部修复功能,比如ComfyUI Impact Pack(FaceDetailer),以及换脸插件Reactor和IPAdapter。 ComfyUI-Impact-Pack 是一个功能强大的插件,专为 ComfyUI …...

专题五_位运算(2)

目录 面试题 01.01. 判定字符是否唯一 解析 题解 268. 丢失的数字 解析 题解 371. 两整数之和 解析 题解 面试题 01.01. 判定字符是否唯一 面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode) 解析 题解 class Solution { public:bool isUnique…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...