MySQL Join 的原理与优化实践

文章目录

    • 引言
    • 一、基础准备:创建环境与示例数据
      • 1. 初始化示例表
      • 2. 示例 Join 查询
      • 3. EXPLAIN 输出分析
    • 二、MySQL Join 的核心算法与执行机制
      • 1. 三种 Join 算法的实现与原理
        • 1.1 Index Nested-Loop Join(INLJ)
        • 1.2 Simple Nested-Loop Join(SNLJ)
        • 1.3 Block Nested-Loop Join(BNLJ)
        • 对比总结
      • 2. Join Buffer 的优化实践
        • 2.1 Join Buffer 的执行原理
        • 2.2 关键配置:Join Buffer 的大小
        • 2.3 Join Buffer 的性能分析
        • 2.4 Join Buffer 示例
      • 3. Batched Key Access(BKA)优化
        • 3.1 BKA 的基本原理
        • 3.2 与传统 Block Nested-Loop Join 的对比
        • 3.3 示例:开启 BKA
      • 4. Multi-Range Read(MRR)优化
    • 三、SQL Join 与非 Join 的选择
      • 1. Join 的代价分析
      • 2. 实际案例:决定是否使用 Join
        • 案例 1:只需一张表的汇总查询
        • 案例 2:多表关联查询
        • 案例总结
    • 四、MySQL Join 查询优化策略
      • 1. 索引设计与调整
        • 1.1 Join 列的索引设计
        • 1.2 索引优化案例
      • 2. 小表驱动大表
        • 2.1 驱动表的选择
        • 2.2 使用 STRAIGHT_JOIN 强制驱动表顺序
      • 3. 提前过滤无用数据
      • 4. 合理调整 Join Buffer
      • 5. BKA 与 MRR 技术
        • 5.1 Batched Key Access(BKA)
        • 5.2 Multi-Range Read(MRR)
    • 五、总结与实践指南
      • 1. MySQL Join 优化的核心思路
      • 2. 面向实践的优化流程


引言

Join 是数据库中最为重要且复杂的操作之一。在数据量较大的场景下,Join 的效率常常决定了整个查询的性能。本文旨在通过深入剖析 MySQL Join 的实现与优化,帮助读者理解其工作原理与实际应用中的性能优化策略。


一、基础准备:创建环境与示例数据

1. 初始化示例表

以下是构建的示例数据库表及其关系:

表名字段说明
usersid, name用户表,主键为 id
ordersid, user_id, product_id, order_date订单表,与 users 是 1 对多关系。
productsid, name, price产品表,与 orders 是多对 1 关系。

表结构及数据:

CREATE TABLE users (id INT PRIMARY KEY,name VARCHAR(50)
);CREATE TABLE orders (id INT PRIMARY KEY,user_id INT,product_id INT,order_date DATE
);CREATE TABLE products (id INT PRIMARY KEY,name VARCHAR(100),price DECIMAL(10, 2)
);INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob');
INSERT INTO products VALUES (1, 'Laptop', 1000.00), (2, 'Phone', 500.00);
INSERT INTO orders VALUES (1, 1, 1, '2024-01-01'), (2, 2, 2, '2024-01-02');

2. 示例 Join 查询

以下是一个简单的三表 Join 查询:

SELECT u.name 用户名, p.name 产品名, o.order_date 订单日期
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id;

查询结果:

用户名产品名订单日期
AliceLaptop2024-01-01
BobPhone2024-01-02

3. EXPLAIN 输出分析

通过 EXPLAIN 查看查询的执行计划:

1


二、MySQL Join 的核心算法与执行机制

1. 三种 Join 算法的实现与原理

在 MySQL 中,Join 的实现依赖三种核心算法。以下分别介绍这些算法的原理、适用场景,以及在实际应用中的优缺点。


1.1 Index Nested-Loop Join(INLJ)

算法原理:

  • 外层表逐行读取记录;
  • 对于每一行记录,使用内层表的索引快速查找匹配行。

适用场景:

  • 内层表的 Join 列已建立索引。
  • 外层表较小,内层表可以快速查找。

性能分析:

  • 扫描行数:
    • 外层表扫描行数:O(n)。
    • 内层表扫描行数:每行只需查找一次索引,时间复杂度为O(log m),扫描行数为1行。
  • 总时间复杂度:O(n log m)
  • 总扫描行数:O(2n)
1.2 Simple Nested-Loop Join(SNLJ)

算法原理:

  • 外层表逐行扫描;
  • 对于每一行记录,内层表全表扫描以寻找匹配行。

适用场景:

  • 内层表未建立索引。
  • 数据量较小时可接受。

性能分析:

  • 扫描行数:
    • 外层表扫描行数:O(n)。
    • 内层表扫描行数:每次全表扫描,复杂度为 O(m)。
  • 总时间复杂度:O(nm)
  • 总扫描行数:O(nm)
1.3 Block Nested-Loop Join(BNLJ)

算法原理:

  • 外层表数据加载到 Join Buffer。
  • 内层表逐行扫描,并与 Join Buffer 中的数据批量匹配。

适用场景:

  • 两张表均无索引。
  • 数据量较大,单次匹配耗时高。

性能分析:

  • 扫描行数:
    • 外层表一次性加载到 Join Buffer,减少多次扫描。
    • 总复杂度:取决于 Join Buffer 大小。

在Join Buffer够大的情况下,扫描行数跟时间复杂度其实跟SNL一样,只不过BNL是内存操作。

对比总结
算法适用场景优点缺点
Index Nested-Loop Join内层表有索引查询高效,减少内层扫描行数依赖索引,外层表仍需扫描所有行
Simple Nested-Loop Join无索引,小数据量简单实现,适合小型数据集内层表全表扫描,效率较低
Block Nested-Loop Join无索引,大数据量缓冲区减少扫描次数依赖内存大小,耗内存

2. Join Buffer 的优化实践

在没有索引支持的情况下,MySQL 使用 Join Buffer 来提升 Join 查询的性能,尤其是涉及大表的 Join 时,Join Buffer 的配置和使用至关重要。

2.1 Join Buffer 的执行原理

Join Buffer 的作用:

  • 临时缓冲区,用于存储外层表的数据,减少内层表的重复扫描次数。
  • 适用于无索引或不适合索引的场景,特别是需要 Block Nested-Loop Join 的情况。

执行步骤:

  1. 从外层表中加载一批数据到 Join Buffer 中。
  2. 内层表逐行扫描,并与 Join Buffer 中的数据逐一匹配。
  3. 若匹配成功,将结果返回;若缓冲区未完全匹配完内层表(Join Buffer 太小,数据太多),清空后继续加载下一批外层表数据。
2.2 关键配置:Join Buffer 的大小

系统变量 join_buffer_size

  • 定义 Join Buffer 的大小(默认值通常为 256KB)。
  • 配置得当时,可以显著减少内层表的扫描次数。
  • 调整示例:
SET join_buffer_size = 8M;

调整前后对比:
假设有以下两张表:

  • 外层表 users 有 1,000 行。
  • 内层表 orders 有 10,000 行。

join_buffer_size 分别设置为 1MB 和 4MB 时的性能表现如下:

join_buffer_size单次缓冲容纳的行数(假设每行大小为 1KB)缓冲批次数内层表扫描次数总扫描行数
1MB1,000110,000(1,000 + 10,000 = 11,000)
4MB4,000110,000(4,000 + 10,000 = 14,000)
2.3 Join Buffer 的性能分析

当 Join Buffer 足够大时:

  • 每次加载更多数据,减少外层表的加载频率。
  • 大幅降低内层表扫描的重复次数。

但是:

  • 若内存不足,可能会导致 MySQL 服务不稳定甚至崩溃。
  • Join Buffer 过大会浪费内存资源,且收益逐渐递减。
2.4 Join Buffer 示例

使用示例 SQL 分析 Join Buffer 的表现:

示例 SQL:

EXPLAIN SELECT u.name, o.id
FROM users u
JOIN orders o ON u.id = o.user_id;

执行计划(无索引):

idselect_typetabletyperowsExtra
1SIMPLEusersALL1000Using temporary
1SIMPLEordersALL10000Using join buffer (Block Nested Loop)

分析:

  • typeALL 表示全表扫描。
  • Extra 中的 Using join buffer 表明 MySQL 使用了 Join Buffer 来优化无索引的 Join 操作。

优化前后执行时间对比:

-- 默认 Join Buffer 大小:
SET join_buffer_size = 256K;-- 调整后的 Join Buffer 大小:
SET join_buffer_size = 4M;

执行结果(在大表测试环境中):

  • 默认 join_buffer_size 时耗时:3.5秒
  • 调整为 4M 后耗时:1.2秒

3. Batched Key Access(BKA)优化

3.1 BKA 的基本原理

BKA(Batched Key Access) 是对传统 Nested-Loop Join 的改进,核心在于:

  • 使用批量索引访问,而非逐条访问索引,提高 I/O 效率。
  • 结合 Join Buffer,减少内存与磁盘之间的数据交换。

BKA 的工作流程:

  1. 批量从外层表加载数据到 Join Buffer。
  2. 根据 Join 条件,将 Join Buffer 中的记录转换为批量索引查找请求。
  3. 内层表按索引批量返回结果。

3.2 与传统 Block Nested-Loop Join 的对比
特性Block Nested-Loop Join(BNLJ)Batched Key Access(BKA)
数据加载方式批量加载外层表数据批量加载外层表数据
索引利用率不依赖索引必须依赖索引
数据访问效率随机访问批量顺序访问
扫描行数较多更少

BKA 的优势:

  • 避免频繁的随机 I/O。
  • 尤其适合内层表索引分布不均或查询条件复杂的情况。

3.3 示例:开启 BKA

默认情况下,MySQL 在特定条件下会自动启用 BKA。可通过以下配置确保 BKA 生效:

SET optimizer_switch = 'batched_key_access=on';

对比示例:
假设外层表 users 有 10,000 行,内层表 orders 有 50,000 行,user_id 上有索引。

  • 使用 BNLJ 时:

    • 外层表批量加载 1,000 行;
    • 每次对内层表随机访问 1,000 次。
  • 使用 BKA 时:

    • 外层表批量加载 1,000 行;
    • 内层表按索引顺序批量访问,减少随机 I/O 次数。

4. Multi-Range Read(MRR)优化

4.1 MRR 的基本原理

MRR(Multi-Range Read) 是另一种索引优化策略,主要用于减少索引范围查询中的随机访问。

原理:

  • 将索引的随机读取转换为顺序读取。
  • 按块读取数据,减少每次 I/O 的开销。

工作流程:

  1. 将索引范围查询的结果缓存在内存中。
  2. 对缓存的结果进行排序,按顺序访问实际数据行。

适用场景:

  • 索引范围查询,如 BETWEEN 或带排序的 ORDER BY
  • 随机访问代价较高的查询。

4.2 示例:开启 MRR

默认情况下,MySQL 会根据场景动态选择是否启用 MRR。可通过以下配置强制启用 MRR:

SET optimizer_switch = 'mrr=on';

MRR 示例对比:

EXPLAIN SELECT o.id
FROM orders o
WHERE o.product_id BETWEEN 10 AND 100;

性能分析:

  • 无 MRR 时,索引随机读取每行记录。
  • 有 MRR 时,索引范围查询的结果会先排序后读取,减少磁盘寻址时间。

三、SQL Join 与非 Join 的选择

在实际场景中,并非所有的多表关联查询都需要通过 Join 实现。在某些情况下,子查询、临时表甚至数据冗余存储可能是更高效的选择。因此,理解 Join 的代价与适用性,并结合具体场景选择合适的实现方式,至关重要。


1. Join 的代价分析

Join 的性能影响因素:

因素说明
表的数据量和分布数据量大、分布不均会导致更多扫描行数或增加 Join Buffer 压力。
索引设计是否合理Join 列上缺乏索引会触发全表扫描,导致性能显著下降。
过滤条件的选择性如果过滤条件的选择性较高(返回行数较少),则 Join 的代价显著降低。
Join 类型不同的 Join 类型(INNER, LEFT, RIGHT, FULL)对外层表和内层表的依赖程度不同,可能影响扫描行数。
查询复杂度复杂查询(如嵌套多层 Join)需要更多的资源和优化策略。

2. 实际案例:决定是否使用 Join

通过两个实际案例分析,在不同场景下选择 Join 或非 Join 的利弊。

案例 1:只需一张表的汇总查询

场景描述:
统计每个用户的订单总金额,不需要关联 products 表。

Join 方案:

SELECT u.name, SUM(p.price) AS total_amount
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id
GROUP BY u.name;

非 Join 方案:

SELECT o.user_id, SUM(p.price) AS total_amount
FROM orders o
JOIN products p ON o.product_id = p.id
GROUP BY o.user_id;

优化分析:

  • 若最终只需用户 ID 和总金额,则非 Join 方案更高效,减少了对 users 表的访问。
  • 如果业务需求需要用户名称,则 Join 必不可少。
案例 2:多表关联查询

场景描述:
查询 2024 年 1 月的订单详情,包括用户名称和产品名称。

Join 方案:

SELECT u.name, p.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id
WHERE o.order_date >= '2024-01-01' AND o.order_date < '2024-02-01';

子查询方案:

WITH filtered_orders AS (SELECT user_id, product_id, order_dateFROM ordersWHERE order_date >= '2024-01-01' AND order_date < '2024-02-01'
)
SELECT u.name, p.name, o.order_date
FROM filtered_orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;

优化分析:

  • 子查询方案提前过滤订单数据,减少了 orders 表的扫描行数,适合大数据量场景。
  • Join 方案更直观,适合中小型数据集。
案例总结
场景Join 是否必要推荐方案
汇总查询(无关联需求)不必要使用单表查询或子查询优化,避免多余 Join。
多表关联查询必要若数据量较大,优先使用子查询减少扫描行数;若数据量小,直接 Join 效率更高。

四、MySQL Join 查询优化策略

在实际工作中,MySQL Join 的优化策略需要结合业务场景和硬件环境动态调整。以下将详细讨论几种常用优化方法,涵盖索引设计、执行顺序调整、Join Buffer 调整,以及 BKA 和 MRR 技术的高效利用。


1. 索引设计与调整

索引是 Join 性能优化的核心之一。在 Join 查询中,MySQL 会优先使用索引快速匹配数据,因此确保 Join 列有合适的索引尤为关键。

1.1 Join 列的索引设计

原则:

  • 对 Join 条件中的列建立索引。
  • 优先考虑复合索引,特别是频繁用于多列匹配的情况。

示例:

-- 为 orders 表的 user_id 和 product_id 列创建复合索引:
ALTER TABLE orders ADD INDEX idx_user_product (user_id, product_id);

索引的作用:

  • 索引可以将 Join 操作从全表扫描(ALL)优化为索引查找(refeq_ref)。
  • 减少内层表扫描的行数,显著降低查询时间。
1.2 索引优化案例

驱动表选择原则:

usersorders 的 Join 查询中,users 是主键表,orders 是从表(外键表)。MySQL 优化器通常会选择行数较少且 Join 列有索引的表作为驱动表(外层表)。

但在此案例中:

  1. 如果 usersorders 的行数接近或 orders 的数据量更大,那么 users 表很可能被选为驱动表。
  2. 如果 orders 数据量较少且 Join 列有索引,则优化器可能选择 orders 表作为驱动表。

案例:
1. 数据准备:批量插入数据

为了更清晰地模拟 MySQL 的行为,我们通过以下存储过程插入测试数据:

DELIMITER //CREATE PROCEDURE generate_test_data()
BEGIN-- 清理旧数据DELETE FROM orders;DELETE FROM users;-- 插入 users 表测试数据(主表:1000 行)DECLARE i INT DEFAULT 1;WHILE i <= 1000 DOINSERT INTO users (id, name) VALUES (i, CONCAT('User', i));SET i = i + 1;END WHILE;-- 插入 orders 表测试数据(从表:10000 行)SET i = 1;WHILE i <= 10000 DOINSERT INTO orders (id, user_id, product_id, order_date)VALUES (i, FLOOR(1 + RAND() * 1000), FLOOR(1 + RAND() * 100), CURDATE() - INTERVAL FLOOR(RAND() * 30) DAY);SET i = i + 1;END WHILE;
END //DELIMITER ;-- 执行存储过程生成数据
CALL generate_test_data();

2. 查询分析:驱动表选择

以下为优化前后的查询对比,分析驱动表的选择及索引的作用。

原始查询

EXPLAIN SELECT users.name, orders.order_date
FROM users
JOIN orders ON users.id = orders.user_id;

执行计划(优化前,未添加索引):
2

驱动表分析:

  • 驱动表(外层表): orders 被选择为驱动表,因为 users 的主键索引使其能够高效响应关联条件。
  • 原因: orders 数据量较大,扫描代价相对较高,但由于 users 的索引能快速匹配,因此优化器倾向于选择 orders 为外层表。

优化查询

orders.user_id 添加索引,增强 Join 列的性能:

ALTER TABLE orders ADD INDEX (user_id);

再次执行查询:

EXPLAIN SELECT users.name, orders.order_date
FROM users
JOIN orders ON users.id = orders.user_id;

执行计划(优化后,添加索引):

3

驱动表分析:

  • 驱动表(外层表): 此时优化器选择了 users 表作为驱动表,因为 orders.user_id 索引使得内层表扫描行数大幅减少。
  • 原因: 索引的引入使得扫描行数显著降低,优化器调整了驱动表选择策略。

3. 驱动表选择的对比总结

在不同场景下,MySQL 的优化器行为会发生变化:

场景外层表(驱动表)内层表扫描行数(总行数)选择理由
未加索引ordersusers10294 + 1 = 10295users 的主键索引效率高,优化器倾向选择大表 orders 为驱动表
加索引usersorders1000 + 10 = 1010orders.user_id 索引生效,显著降低了内层表扫描行数

为什么未加索引时,扫描的行数是10249而不是10000?
在没有为 orders.user_id 添加索引时,MySQL 对 orders 表的扫描是全表扫描 (ALL)。
在这种情况下,优化器对扫描行数的估算基于表统计信息,例如数据的分布和块读取情况。
如果表的统计信息不准确或者数据分布较为不均衡(如随机生成的 user_id 有部分重复值),扫描时可能会多读取额外的数据块。
所以MySQL 会为了缓存块或磁盘预读而额外扫描相邻数据行,可能导致扫描行数增加。

2. 小表驱动大表

2.1 驱动表的选择

原则:

  • 优先选择小表作为驱动表(即外层表)。
  • 外层表的每一行都会触发内层表的扫描,因此外层表越小,扫描次数越少。

示例:

-- 默认 Join 查询,MySQL 自动选择驱动表:
SELECT u.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id;
2.2 使用 STRAIGHT_JOIN 强制驱动表顺序

在某些情况下,MySQL 的查询优化器可能会错误选择驱动表顺序。可以使用 STRAIGHT_JOIN 强制指定驱动表:

SELECT STRAIGHT_JOIN u.name, o.order_date
FROM orders o
JOIN users u ON u.id = o.user_id;

效果:

  • 强制 orders 为外层表,减少了扫描行数。

3. 提前过滤无用数据

原则:

  • 尽量在 Join 之前过滤掉无关数据,减少 Join 操作时的行数。
  • 过滤可以通过子查询、WHERE 条件提前完成。

示例优化:

-- 原始查询:过滤条件放在 Join 后
SELECT u.name, p.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN products p ON o.product_id = p.id
WHERE o.order_date > '2024-01-01';

优化查询:将过滤提前:

SELECT u.name, p.name, o.order_date
FROM (SELECT * FROM orders WHERE order_date > '2024-01-01') o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;

优化效果:

  • 原始查询需要扫描 orders 表的所有数据。
  • 优化后,提前过滤无关订单数据,减少了外层表的数据量,降低了 Join 的行数和成本。

4. 合理调整 Join Buffer

在无索引或索引不可用的情况下,Join Buffer 是优化 Block Nested-Loop Join 的关键。其大小直接影响外层表加载的行数和内层表的扫描效率。

默认值:

  • 通常 MySQL 的默认 join_buffer_size 为 256KB。

调整方式:

SET join_buffer_size = 4M;

注意事项:

  • Join Buffer 大小不宜设置过大,以免占用过多内存导致系统不稳定。
  • 可根据业务测试结果动态调整大小。

5. BKA 与 MRR 技术

5.1 Batched Key Access(BKA)

原理:

  • 使用批量索引读取,而非逐条访问。
  • 减少了随机 I/O 次数,提高查询性能。

BKA 优化示例:

SET optimizer_switch = 'batched_key_access=on';SELECT u.name, o.order_date
FROM users u
JOIN orders o ON u.id = o.user_id;

效果对比:

  • 无 BKA:每次外层表记录需要随机查找内层表索引。
  • 有 BKA:批量加载外层表数据,内层表按索引顺序批量返回结果。
5.2 Multi-Range Read(MRR)

原理:

  • 将索引的随机读取转换为顺序读取,优化索引范围查询的效率。

适用场景:

  • 索引范围查询,如 BETWEEN 或带排序的 ORDER BY 查询。

MRR 示例:

SET optimizer_switch = 'mrr=on';EXPLAIN SELECT o.id
FROM orders o
WHERE o.product_id BETWEEN 10 AND 100;

优化效果:

  • 无 MRR 时,索引随机读取每行记录,导致更多磁盘寻址操作。
  • 开启 MRR 后,索引范围查询结果先排序,减少磁盘 I/O。

五、总结与实践指南

通过本文的深入解析,可以总结出以下优化建议:

1. MySQL Join 优化的核心思路

  • 索引优先: 确保 Join 列有适当的索引,优先使用覆盖索引。
  • 合理选择驱动表: 优先选择小表作为驱动表,使用 STRAIGHT_JOIN 控制查询顺序。
  • 动态调整 Join Buffer: 根据数据量测试合理的 Join Buffer 大小。
  • 利用高级技术: 在适用场景中开启 BKA 和 MRR,优化随机 I/O。

2. 面向实践的优化流程

  1. 使用 EXPLAIN 分析查询计划,定位性能瓶颈。
  2. 针对 Join 列设计索引,尽量减少全表扫描。
  3. 在无索引场景下,调整 Join Buffer,避免频繁磁盘 I/O。
  4. 在大数据量查询中,提前过滤无关数据,减少行数。
  5. 结合具体场景,选择合适的算法与优化技术。

在这里插入图片描述

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

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

相关文章

阿里Qwen系列开源模型介绍

模型种类丰富 Qwen2&#xff1a;包含Qwen2-0.5b、Qwen2-1.5b、Qwen2-7b、Qwen2-57b-a14b以及Qwen2-72b等五种规模的预训练和指令微调模型&#xff0c;其在多语言处理、长文本处理、代码生成、数学和逻辑推理等能力上&#xff0c;在mmlu、gpqa、humaneval等国际测评中得到了验证…

Redis设计与实现 学习笔记 第二十章 Lua脚本

Redis从2.6版本引入对Lua脚本的支持&#xff0c;通过在服务器中嵌入Lua环境&#xff0c;Redis客户端可以使用Lua脚本&#xff0c;直接在服务器端原子地执行多个Redis命令。 其中EVAL命令可以直接对输入的脚本进行求值&#xff1a; 而使用EVALSHA命令则可以根据脚本的SHA1校验…

DevOps 之 CI/CD入门操作 (二)

CI/CD简介 基于Jenkins拉取GitLab的SpringBoot代码进行构建发布到测试环境实现持续集成 基于Jenkins拉取GitLab指定发行版本的SpringBoot代码进行构建发布到生产环境实现CD实现持续部署 一、CI流程 1.1 新建项目 新建一个简单的springboot项目 写一个简单的Controller 运行测…

C++ STL - vector/list讲解及迭代器失效

vector 使用 vector 是一个动态数组. 构造/拷贝构造/赋值重载函数 int main() {// 是一个模板, 在实例化的时候, 需要指明类型std::vector<int> first; // 一个空的数组std::vector<int> second (4,100); // 设置初始空间大小为 4 个int, 全部初始化为 100std::v…

AWS 新加坡EC2 VPS 性能、线路评测及免费注意事项

原文论坛给你更好的阅读讨论体验&#x1f490;&#xff1a; AWS 新加坡EC2 VPS 性能、线路评测及免费注意事项 - VPS - 波波论坛 引言 对于那些习惯薅“羊毛”的朋友来说&#xff0c; AWS 的 免费套餐 可能已经非常熟悉。这台vps是我用外币卡薅的免费的12个月的机器&#xf…

TritonServer中加载模型,并在Gunicorn上启动Web服务调用模型

TritonServer中加载模型,并在Gunicorn上启动Web服务调用模型 一、TritonServer中加载模型1.1 搭建本地仓库1.2 配置文件1.3 服务端代码1.4 启动TritonServer二、Gunicorn上启动Web服务2.1 安装和配置Gunicorn2.2 启动Gunicorn三、调用模型四、性能优化与监控五、总结在深度学习…

容器安全检测和渗透测试工具

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect Docker-bench-…

使用ENSP实现NAT

一、项目拓扑 二、项目实现 1.路由器AR1配置 进入系统试图 sys将路由器命名为R1 sysname R1关闭信息中心 undo info-center enable进入g0/0/0接口 int g0/0/0将g0/0/0接口IP地址配置为12.12.12.1/30 ip address 12.12.12.1 30进入e0/0/1接口 int g0/0/1将g0/0/1接口IP地址配置…

pnpm:包管理的新星,平替 npm 和 yarn

​ pnpm&#xff0c;一个老牌的 node.js 包管理器&#xff0c;支持 npm 的所有功能&#xff0c;完全足以用来替代 npm。它采用全局存储&#xff0c;每个项目内部使用了硬链接&#xff0c;所以很省空间&#xff0c;安装速度快。 本文介绍下 pnpm 的基本概念&#xff0c;安装、…

【大数据学习 | Spark-Core】Spark的分区器(HashPartitioner和RangePartitioner)

之前学过的kv类型上面的算子 groupby groupByKey reduceBykey sortBy sortByKey join[cogroup left inner right] shuffle的 mapValues keys values flatMapValues 普通算子&#xff0c;管道形式的算子 shuffle的过程是因为数据产生了打乱重分&#xff0c;分组、排序、join等…

计算机网络基础全攻略:探秘网络构建块(1/10)

一、计算机网络基础概念 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路和通信设备连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统…

游戏陪玩系统开发功能需求分析

电竞游戏陪玩系统是一种专门为游戏玩家提供陪伴、指导和互动服务的平台。这类系统通常通过专业的陪玩师&#xff08;也称为陪练师&#xff09;为玩家提供一对一或多对一的游戏陪伴服务&#xff0c;帮助玩家提升游戏技能、享受游戏乐趣&#xff0c;甚至解决游戏中的各种问题。电…

关于SpringBoot集成Kafka

关于Kafka Apache Kafka 是一个分布式流处理平台&#xff0c;广泛用于构建实时数据管道和流应用。它能够处理大量的数据流&#xff0c;具有高吞吐量、可持久化存储、容错性和扩展性等特性。 Kafka一般用作实时数据流处理、消息队列、事件架构驱动等 Kafka的整体架构 ZooKeeper:…

Linux 下的IO模型

一&#xff1a;四种IO模 1.1&#xff1a;阻塞式IO&#xff08;最简单&#xff0c;最常用&#xff0c;效率最低&#xff09; 阻塞I/O 模式是最普遍使用的I/O 模式&#xff0c;大部分程序使用的都是阻塞模式的I/O 。 缺省情况下&#xff08;及系统默认状态&#xff09;&#xf…

vue3项目部署在阿里云轻量应用服务器上

文章目录 概要整体部署流程技术细节小结 概要 vue3前端项目部署在阿里云轻量服务器 整体部署流程 首先有一个Vue3前端项目和阿里云应用服务器 确保环境准备 如果是新的服务器&#xff0c;在服务器内运行以下命令更新软件包 sudo apt update && sudo apt upgrade -y …

tcpdump交叉编译

TCPDUMP在Libpcap上开发。 首先需要编译libcap。 网上那么多教程&#xff0c;下载地址都只给了一个英文的官网首页&#xff0c; 你尽可以试试&#xff0c;从里面找到下载地址都要费半天时间。 \color{red}网上那么多教程&#xff0c;下载地址都只给了一个英文的官网首页&#…

KubeSphere 最佳实战:K8s 构建高可用、高性能 Redis 集群实战指南

首发&#xff1a;运维有术。 本指南将逐步引导您完成以下关键任务&#xff1a; 安装 Redis&#xff1a;使用 StatefulSet 部署 Redis。自动或手动配置 Redis 集群&#xff1a;使用命令行工具初始化 Redis 集群。Redis 性能测试&#xff1a;使用 Redis 自带的 Benchmark 工具进…

02 python基础 python解释器安装

首先在网站&#xff1a;Welcome to Python.org进行下载安装python 最新的解释器不一定是最好的&#xff0c;最稳定的才一定是最好的&#xff1b;要关注解释器最后维护 的时间。 一、python的安装 python安装的时候一定要在下载勾选好添加path环境 安装的时候尽量选择好自己的安…

java编程开发基础,正则表达式的使用案例Demo

java编程开发基础,正则表达式的使用案例Demo!实际开发中&#xff0c;经常遇到一些字符串&#xff0c;信息的裁剪和提取操作&#xff0c;正则表达式是经常使用的&#xff0c;下面的案例&#xff0c;可以帮助大家快速的了解和熟悉&#xff0c;正则表达式的使用技巧。 package com…

Windows Pycharm 远程 Spark 开发 PySpark

一、环境版本 环境版本PyCharm2024.1.2 (Professional Edition)Ubuntu Kylin16.04Hadoop3.3.5Hive3.1.3Spark2.4.0 二、Pycharm远程开发 文件-远程-开发 选择 SSH连接&#xff0c;连接虚拟机&#xff0c;选择项目目录即可远程开发