MySQL高级SQL秘籍:性能飞升之路

MySQL高级SQL秘籍:性能飞升之路

引言:解锁 MySQL 的隐藏力量

在日常开发中,MySQL 作为一款广泛使用的关系型数据库,相信大家都不陌生。无论是搭建小型 Web 应用,还是处理企业级大数据量存储,MySQL 都凭借其稳定的性能、开源特性和丰富的功能,成为众多开发者的首选。你或许已经熟练掌握了基本的增删改查操作,像从用户表中查询用户信息,或是往订单表中插入新订单记录 ,这些基础操作就像我们每天都要使用的 "常规武器",支撑着系统的日常运转。但你是否想过,MySQL 这座 "宝藏" 里,还有更多强大的功能等待我们去挖掘?多数人在日常工作中,仅仅使用了 MySQL 80% 的基础功能,而剩下那 20% 的高级功能,却能解决 90% 的复杂问题!从优化高并发场景下的查询性能,到处理复杂的数据分析任务,这些高级 SQL 技巧将带你突破性能瓶颈,让你的数据处理能力实现质的飞跃 。今天,就让我们一起揭开这 10 种高级 SQL 的神秘面纱,开启 MySQL 的进阶之旅!

执行计划:SQL 的 X 光片

在深入探索高级 SQL 之前,我们需要一把 "手术刀",来剖析 SQL 语句的执行过程,这就是EXPLAIN关键字。它就像是 SQL 的 X 光片,能让我们清晰地看到数据库引擎如何执行查询,帮助我们找出潜在的性能瓶颈 。

当我们在 SQL 语句前加上EXPLAIN,MySQL 会返回一个包含查询执行计划的结果集,其中包含了许多关键信息,比如查询的执行顺序、表的访问类型、使用的索引等。这里面,有几个字段尤其值得我们重点关注:

  • type :这是查询的访问类型,从最优到最差依次为system > const > eq_ref > ref > range > index > ALL 。比如,const类型表示通过主键或唯一索引直接定位到一行记录,查询速度最快;而ALL则表示全表扫描,性能最差,应尽量避免。

  • key:显示 MySQL 实际使用的索引名称。如果该字段为空,表示查询没有使用索引,这时候就需要检查查询条件和索引设置,看是否有优化的空间。

  • rows:MySQL 预估需要扫描的行数,这个值越小越好。它是评估查询效率的重要指标之一,数值越大,通常意味着查询需要扫描更多的数据,性能也就越差。

  • Extra :提供了额外的执行信息,比如Using where表示使用了 WHERE 条件过滤数据;Using index表示使用了覆盖索引,无需回表查询,性能较高;而Using temporaryUsing filesort则通常意味着需要创建临时表或进行额外的排序操作,可能存在性能问题 。

举个例子,假设有一个用户表users,包含id(主键)、nameage等字段,我们执行以下查询:

sql 复制代码
EXPLAIN SELECT * FROM users WHERE name = '张三';

执行结果中,如果typerefkeyname字段上的索引,rows预估扫描行数较少,ExtraUsing where; Using index,这说明查询使用了name索引,并且通过索引覆盖避免了回表操作,性能较好。但如果typeALLkeyNULL,那就意味着全表扫描,索引未生效,需要进一步优化,比如检查name字段是否有合适的索引,或者查询条件是否正确 。通过EXPLAIN,我们就像拥有了透视眼,能够深入了解 SQL 查询的内部运作,为性能优化打下坚实的基础 。

高级索引策略:性能的基石

索引是 MySQL 性能优化的关键,而高级索引策略则是让查询性能实现飞跃的 "秘密武器"。合理地使用索引,可以大大减少数据扫描的范围,提高查询效率 。接下来,让我们深入探讨几种高级索引技巧 。

覆盖索引:无需回表的速度魔法

在数据库查询中,回表操作往往是影响性能的一大因素。当我们使用普通索引查询时,如果查询所需的字段不在索引中,数据库就需要根据索引找到主键,再通过主键去聚簇索引中查询完整的数据行,这个过程就像你在图书馆找书,先通过目录找到书架编号,再去书架上找书,比较耗时。而覆盖索引则是一种特殊的索引策略,它能让数据库在执行查询时,仅仅通过读取索引本身就能获取到所有需要的数据,而无需再去访问原始的数据表,避免了回表操作,显著提升查询性能。

假设我们有一个products表,包含id(主键)、namepricecategory_idstock_quantity等字段,现在我们想查询某个分类下价格最高的 10 个商品的名字和价格:

sql 复制代码
SELECT name, price FROM products WHERE category_id = 101 ORDER BY price DESC LIMIT 10;

如果只存在普通索引idx_category_price (category_id, price),数据库会先利用这个索引找到category_id = 101的商品,并按price排序。但由于name字段不在这个索引里,数据库在找到符合条件的商品id后,还需要进行 "回表" 操作,去products表中获取name字段。对于大量记录来说,这会产生很多随机 I/O,影响查询效率。

为了将这个查询变成覆盖索引,我们可以这样创建索引:

sql 复制代码
-- 创建一个覆盖索引,包含了查询所需的所有字段
CREATE INDEX idx_category_price_name ON products (category_id, price, name);

现在,当再次执行上述查询时,数据库可以直接扫描idx_category_price_name这个索引。因为category_id用于过滤,price用于排序,而nameprice是需要返回的字段,所有这些数据都已经在索引中了。数据库无需回表,查询效率会得到质的提升 。在高并发的电商商品查询场景中,使用覆盖索引可以让用户快速获取商品名称和价格,提升购物体验,减少服务器压力 。

索引下推:减少回表的利器

MySQL 5.6 引入了一个强大的优化 ------ 索引下推(Index Condition Pushdown,ICP) 。在理解索引下推之前,我们先来看看旧版本的查询方式。假设我们有一个employees表,结构如下:

sql 复制代码
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department_id INT,
    salary DECIMAL(10,2),
    hire_date DATE,
    INDEX idx_department_salary (department_id, salary)
);

当执行查询SELECT employee_id, first_name, last_name FROM employees WHERE department_id = 5 AND salary > 50000;时,在没有索引下推的情况下,MySQL 的查询执行步骤如下:

  1. 索引扫描 :MySQL 使用联合索引idx_department_salary查找department_id = 5的所有记录。

  2. 数据页访问 :对于索引扫描得到的每一个department_id = 5的记录,MySQL 都需要访问相应的数据页来获取salary的值,以判断是否满足salary > 50000的条件。

  3. 条件过滤 :只有当salary > 50000时,才将记录返回给客户端。

这种方式的缺点在于,即使salary > 50000的条件在索引层是可评估的,但由于没有索引下推,MySQL 仍然需要访问大量的数据页进行条件判断,导致较高的磁盘 I/O 开销,尤其是在department_id = 5有大量记录时。

而启用索引下推后,执行同样的查询,MySQL 的查询执行步骤如下:

  1. 索引扫描 :MySQL 使用联合索引idx_department_salary查找department_id = 5的所有记录。

  2. 索引条件过滤 :在索引扫描的过程中,MySQL 直接在索引层检测salary > 50000的条件。对于不满足salary > 50000的记录,MySQL 可以直接忽略,避免访问相应的数据页。

  3. 数据页访问 :只有在索引层同时满足department_id = 5salary > 50000的记录,MySQL 才需要访问数据页获取完整的记录。

通过索引下推,MySQL 将部分过滤条件下推到索引扫描阶段,减少了不必要的数据行检索,从而提高了查询效率。在企业员工信息管理系统中,当需要频繁查询某个部门中薪资高于特定值的员工信息时,索引下推能显著提升查询速度,节省大量时间 。

前缀索引:空间与效率的平衡

在处理一些超长文本字段时,如文章标题、URL 等,如果对整个字段创建索引,不仅会占用大量的磁盘空间,还会降低写入和更新的性能。这时,前缀索引就派上用场了。前缀索引允许我们只对字符串的前 N 个字符建立索引,而不是整个字符串,从而在一定程度上平衡了空间占用和查询效率。

例如,我们有一个articles表,用于存储文章信息,其中title字段可能很长:

sql 复制代码
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(500) NOT NULL,
    body TEXT,
    PRIMARY KEY(id),
    INDEX(title(25)) -- 对title这个字段只取其前25个字符作为索引依据
);

这样,当我们执行查询SELECT id, title FROM articles WHERE title LIKE 'MySQL优化%';时,MySQL 会使用前缀索引快速定位到匹配的记录。虽然前缀索引不能完全覆盖整个字段,但对于大多数只需要匹配前缀的查询场景来说,已经足够高效,并且大大减少了索引的存储空间。

不过,前缀索引也有一些局限性,比如它无法用于GROUP BYORDER BY操作,因为这些操作需要对索引字段的完整值进行排序或分组。所以,在使用前缀索引时,需要根据实际的查询需求和数据特点来权衡利弊 。在新闻网站的文章检索功能中,使用前缀索引可以快速定位包含特定关键词前缀的文章标题,提升检索速度 。

窗口函数:跨行计算的神兵

MySQL 8.0 引入的窗口函数(Window Function),为我们打开了一扇处理复杂数据分析的新大门。它就像是一个 "跨行计算的神兵",能在不改变原有行结构的基础上,对一组相关行进行计算,让我们轻松实现排名、移动平均、累计求和等复杂操作 。

窗口函数的基本语法如下:

sql 复制代码
函数名([参数]) OVER ([PARTITION BY 分组列] [ORDER BY 排序列 [ASC|DESC]] [ROWS/RANGE BETWEEN 窗口范围])

其中,PARTITION BY用于将数据分成不同的分区,类似于GROUP BY分组,但不会合并行;ORDER BY指定分区内数据的排序方式;ROWS/RANGE BETWEEN则定义了窗口的范围,比如ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING表示窗口范围为当前行及其前后各一行 。

排名统计:谁是薪资王者?

在员工薪资管理中,我们常常需要对员工的薪资进行排名,以了解每个员工在团队中的薪资水平。假设我们有一个employees表,包含idnamedepartmentsalary等字段,现在要给每个部门的员工按薪资从高到低排名 :

sql 复制代码
SELECT 
    department,
    name,
    salary,
    -- 连续排名,即使薪资相同,排名也不同
    ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_num,
    -- 跳跃排名,薪资相同排名相同,后续排名跳过
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank_num,
    -- 连续排名,薪资相同排名相同,后续排名不跳过
    DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dense_rank_num
FROM 
    employees;

在这个例子中,ROW_NUMBER()函数会为每个部门的员工分配一个唯一的连续序号;RANK()函数在遇到薪资相同的员工时,会分配相同的排名,并跳过后续的排名;DENSE_RANK()函数则在薪资相同时,分配相同排名,但后续排名不会跳过 。通过这三个函数的对比,我们可以更全面地了解员工薪资的分布情况 。

分组 TopN:筛选部门精英

如果我们想找出每个部门薪资最高的前 N 名员工,窗口函数也能轻松实现。以找出每个部门薪资最高的 2 名员工为例:

sql 复制代码
WITH emp_rank AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS row_num
    FROM 
        employees
)
SELECT 
    department,
    name,
    salary,
    row_num
FROM 
    emp_rank
WHERE 
    row_num <= 2;

这里我们先使用WITH子句创建了一个名为emp_rank的临时结果集,在这个临时结果集中,使用ROW_NUMBER()函数为每个部门的员工按薪资排名。然后在主查询中,从emp_rank中筛选出排名前 2 的员工,这样就能快速定位每个部门的高薪精英 。

累计计算:洞悉业务增长趋势

在电商业务中,我们经常需要计算销售额的累计值,以了解业务的增长趋势。假设有一个sales表,包含month(月份)、amount(销售额)字段,计算每月的累计销售额:

sql 复制代码
SELECT 
    month,
    amount,
    SUM(amount) OVER (ORDER BY month) AS total_amount
FROM 
    sales;

在这个查询中,SUM(amount) OVER (ORDER BY month)表示按照month字段的顺序,对amount进行累计求和。随着month的递增,total_amount会不断累加,让我们清晰地看到销售额的增长轨迹 。通过累计计算,电商运营人员可以直观地了解业务的发展态势,为制定营销策略提供数据支持 。

通用表表达式(CTE):简化复杂查询的神器

MySQL 8.0 引入的通用表表达式(Common Table Expression,CTE),就像是一把神奇的钥匙,为我们打开了简化复杂查询的大门 。CTE 允许我们在单个查询中定义临时的命名结果集,然后在后续的查询中像普通表一样引用它 。这不仅大大提升了查询的可读性,还为处理复杂的数据逻辑提供了更加优雅的解决方案 。

提升可读性:复杂查询的拆解利器

在日常开发中,我们经常会遇到一些复杂的查询,涉及多个表的关联、多层嵌套子查询,这些查询往往像一团乱麻,让人望而生畏。而 CTE 就像是一位 "整理大师",能够将复杂的查询分解为多个逻辑清晰的步骤,每个步骤都可以通过一个有意义的名称来标识,让代码的可读性大大提升 。

例如,假设我们有一个电商数据库,包含orders(订单表)、users(用户表)和products(产品表) 。现在我们需要查询出每个活跃用户(近 30 天内有登录记录)在 2024 年购买的总金额大于 10000 元的订单信息,包括用户姓名、邮箱、订单金额和订单日期 。如果使用传统的嵌套子查询,代码可能会像这样:

sql 复制代码
SELECT 
    u.name, 
    u.email, 
    o.amount, 
    o.order_date
FROM 
    users u
JOIN 
    (
        SELECT 
            user_id, 
            SUM(amount) as total_amount, 
            order_date
        FROM 
            orders
        WHERE 
            YEAR(order_date) = 2024
        GROUP BY 
            user_id, order_date
        HAVING 
            SUM(amount) > 10000
    ) o ON u.id = o.user_id
JOIN 
    (
        SELECT 
            DISTINCT user_id
        FROM 
            user_logs
        WHERE 
            last_active_date > DATE_SUB(NOW(), INTERVAL 30 DAY)
    ) a ON u.id = a.user_id;

这段代码虽然能够实现功能,但多层嵌套的子查询让人眼花缭乱,维护起来也非常困难。一旦需求发生变化,比如需要增加一个查询条件,修改代码就如同在迷宫中穿梭,一不小心就会迷失方向 。

现在,让我们使用 CTE 来改写这个查询:

sql 复制代码
WITH 
    -- 找出2024年订单总金额大于10000元的订单
    high_value_orders AS (
        SELECT 
            user_id, 
            SUM(amount) as total_amount, 
            order_date
        FROM 
            orders
        WHERE 
            YEAR(order_date) = 2024
        GROUP BY 
            user_id, order_date
        HAVING 
            SUM(amount) > 10000
    ),
    -- 找出近30天内活跃的用户
    active_users AS (
        SELECT 
            DISTINCT user_id
        FROM 
            user_logs
        WHERE 
            last_active_date > DATE_SUB(NOW(), INTERVAL 30 DAY)
    )
-- 最终查询:既是高价值又是活跃的用户的订单信息
SELECT 
    u.name, 
    u.email, 
    h.total_amount, 
    h.order_date
FROM 
    users u
JOIN 
    high_value_orders h ON u.id = h.user_id
JOIN 
    active_users a ON u.id = a.user_id;

通过 CTE,我们将复杂的查询逻辑拆分成了两个独立的部分:high_value_orders用于筛选高价值订单,active_users用于筛选活跃用户 。最后在主查询中,通过关联这两个 CTE,轻松得到我们需要的结果 。这样的代码结构清晰,每个 CTE 都有明确的职责,阅读和维护起来都更加方便 。即使后续需求发生变化,我们也只需要修改对应的 CTE 部分,而不会影响到整个查询的其他部分 。在电商平台的数据分析场景中,使用 CTE 可以让分析师更快速地理解和修改查询逻辑,提高工作效率 。

支持递归:树形数据查询的救星

除了提升可读性,CTE 还有一个 "杀手级" 功能 ------ 支持递归查询 。这使得 CTE 在处理树形结构或层次数据时,如鱼得水 。无论是查询组织架构中的员工层级关系,还是分类目录中的商品层级,递归 CTE 都能轻松应对 。

以查询公司的部门树为例,假设我们有一个departments表,包含id(部门 ID)、name(部门名称)和parent_id(上级部门 ID)字段 。现在我们要查询出某个部门及其所有子部门的信息 。使用递归 CTE,代码如下:

sql 复制代码
WITH RECURSIVE department_tree AS (
    -- 锚点成员:初始查询,找到指定部门
    SELECT 
        id, 
        name, 
        parent_id, 
        1 AS level
    FROM 
        departments
    WHERE 
        id = 101  -- 假设要查询的部门ID为101
    UNION ALL
    -- 递归成员:通过关联上一层结果,查询子部门
    SELECT 
        d.id, 
        d.name, 
        d.parent_id, 
        dt.level + 1
    FROM 
        departments d
    INNER JOIN 
        department_tree dt ON d.parent_id = dt.id
)
-- 主查询:获取部门树结果
SELECT 
    *
FROM 
    department_tree;

在这个查询中,WITH RECURSIVE关键字表示这是一个递归 CTE 。首先,通过初始查询(锚点成员)找到指定部门,并将其层级设置为 1 。然后,通过递归查询(递归成员),不断地关联departments表和department_tree CTE,找到每个部门的子部门,并将层级加 1 。最终,主查询从department_tree CTE 中获取所有部门的信息,形成完整的部门树 。

通过递归 CTE,我们可以轻松地实现对树形数据的深度遍历,而无需使用复杂的自连接或临时表 。这不仅简化了代码,还提高了查询的效率和可读性 。在企业的组织架构管理系统中,递归 CTE 可以帮助管理员快速查询某个部门的所有下属部门,方便进行人员管理和资源分配 。

JSON 类型与函数:关系型数据库中的半结构化数据处理

随着互联网的飞速发展,数据的多样性和复杂性与日俱增,传统关系型数据库中严格的结构化表结构,在面对一些动态、多变的数据时,常常显得力不从心 。而 MySQL 5.7 及以上版本引入的 JSON 类型,就像是为关系型数据库注入了一股 "柔性力量",让它能够灵活地处理半结构化数据 。

什么是 JSON 类型

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以简洁、易读的文本格式来表示结构化数据 。在 MySQL 中,JSON 类型可以存储符合 JSON 标准的对象和数组,比如一个用户的扩展信息:

json 复制代码
{
    "name": "李四",
    "age": 30,
    "address": {
        "city": "上海",
        "district": "浦东新区",
        "street": "世纪大道1号"
    },
    "hobbies": ["篮球", "阅读", "旅行"]
}

这样的数据结构,相比于传统的关系型表结构,更加灵活和直观 。它可以轻松地存储一些动态变化的字段,而无需频繁地修改表结构 。例如,在一个电商商品表中,除了商品的基本信息,如名称、价格、库存等,还可能有一些个性化的属性,像商品的材质、适用人群、尺寸规格等,这些属性对于不同的商品可能差异较大 。如果使用传统的关系型表,就需要为每个可能的属性都创建一个列,这不仅会导致表结构变得非常复杂,而且在实际使用中,很多列可能大部分时间都是空的 。而使用 JSON 类型,我们可以将这些个性化属性统一存储在一个 JSON 字段中,每个商品的属性可以根据实际情况自由组合,大大提高了数据存储的灵活性 。

JSON 类型的优势

  1. 灵活的数据存储:JSON 类型允许字段的无限扩展,无需预先定义所有列 。这使得在面对一些不确定的数据结构时,我们可以轻松应对 。比如,在一个日志系统中,需要记录用户的操作行为,每个操作可能包含不同的参数和信息 。使用 JSON 类型,我们可以将这些操作信息以 JSON 格式存储,无论参数如何变化,都能方便地记录下来 。

  2. 支持复杂数据结构:JSON 不仅支持字符串、整型、浮点数等基本数据类型,还支持嵌套的 JSON 对象和数组 。这使得我们可以将一些具有层次结构的数据,如组织架构、商品分类目录等,以一种自然的方式存储在数据库中 。例如,一个公司的组织架构可以表示为一个嵌套的 JSON 对象,每个部门又可以包含下属部门和员工信息,这种数据结构能够清晰地反映出组织的层级关系 。

  3. 简化表结构设计 :使用 JSON 类型可以减少表的列数,避免频繁执行ALTER TABLE操作来添加新列 。这对于需要频繁扩展字段的业务场景非常有用 。比如,在一个在线教育平台中,课程的属性可能会随着业务的发展不断增加,如课程的难度等级、学习时长、是否有证书等 。如果使用传统的关系型表,每次添加新属性都需要修改表结构,而使用 JSON 类型,只需要在 JSON 字段中添加新的键值对即可,大大简化了表结构的维护 。

JSON 函数的使用

MySQL 提供了一系列强大的 JSON 函数,用于对 JSON 类型的数据进行查询、修改和验证 。

  1. 查询 JSON 数据JSON_EXTRACT函数和->操作符可以根据 JSON 路径表达式从 JSON 数据中提取值 。例如,我们有一个users表,其中info字段存储用户的扩展信息,现在要查询所有用户的城市:
sql 复制代码
SELECT JSON_EXTRACT(info, '$.address.city') AS city FROM users;
-- 或者使用 -> 操作符,语法更简洁
SELECT info->'$.address.city' AS city FROM users;

如果要提取数组中的某个元素,比如查询每个用户的第一个爱好,可以这样写:

sql 复制代码
SELECT info->'$.hobbies[0]' AS first_hobby FROM users;
  1. 修改 JSON 数据JSON_SET函数可以用于设置 JSON 数据中的值,如果路径不存在则会创建新的路径 。例如,要将用户李四的城市修改为 "北京",并添加一个新的字段 "phone":
sql 复制代码
UPDATE users
SET info = JSON_SET(info, '$.address.city', '北京', '$.phone', '13800138000')
WHERE name = '李四';

JSON_REPLACE函数则只会替换已存在路径的值 。比如,要修改李四的年龄:

sql 复制代码
UPDATE users
SET info = JSON_REPLACE(info, '$.age', 31)
WHERE name = '李四';
  1. JSON 条件查询 :我们还可以在WHERE子句中使用 JSON 路径表达式进行条件查询 。例如,查询年龄大于 30 岁的用户:
sql 复制代码
SELECT * FROM users WHERE info->'$.age' > 30;

如果要查询爱好中包含 "篮球" 的用户,则需要使用JSON_CONTAINS函数:

sql 复制代码
SELECT * FROM users WHERE JSON_CONTAINS(info->'$.hobbies', '"篮球"');
  1. 创建虚拟列与索引优化 :由于不能直接对 JSON 字段建索引,但可以通过创建虚拟列并为其加索引提升性能 。例如,为了加速对用户城市的查询,可以创建一个虚拟列city_v,并为其添加索引:
sql 复制代码
ALTER TABLE users
ADD COLUMN city_v AS (info->>'$.address.city') STORED;
CREATE INDEX idx_city ON users(city_v);

这样在查询城市相关信息时,就可以利用索引加速,提高查询效率 。在一个拥有海量用户数据的社交平台中,通过对用户地址信息中的城市字段创建虚拟列和索引,可以快速筛选出某个城市的用户,为基于地理位置的社交功能提供高效的数据支持 。

总结:开启高性能 SQL 之旅

到这里,我们已经一起探索了 MySQL 的 10 种高级 SQL 技巧,从执行计划的 "透视眼",到索引策略的 "性能基石";从窗口函数的 "跨行计算神兵",到 CTE 的 "复杂查询神器",再到 JSON 类型与函数的 "半结构化数据处理专家" 。这些技巧就像是一把把钥匙,能够解锁 MySQL 的隐藏力量,让你的 SQL 查询性能实现质的飞跃 。希望你能将这些技巧运用到实际的工作中,不断优化 SQL 查询,提升数据库操作效率 。相信随着对这些高级 SQL 技巧的熟练掌握,你在处理数据库相关任务时,将更加得心应手,轻松应对各种复杂的数据场景 。未来,随着数据库技术的不断发展,MySQL 也将不断进化,带来更多强大的功能和优化 。让我们一起保持学习的热情,持续探索 MySQL 的无限可能,在数据的海洋中乘风破浪 ! 如果你在学习和实践过程中有任何疑问或心得,欢迎在评论区留言分享,让我们一起交流进步 。

相关推荐
迷藏4942 小时前
# 发散创新:用 Rust实现高性能测试框架的底层逻辑与实战演练
java·开发语言·后端·python·rust
Victor3562 小时前
MongoDB(64)如何优化写操作性能?
后端
浮尘笔记2 小时前
PHP中常规通用接口验签加密规则设计
开发语言·后端·网络安全·php
Victor3562 小时前
MongoDB(63)如何配置数据压缩?
后端
毕设源码-钟学长2 小时前
【开题答辩全过程】以 基于Springboot的在线考试系统为例,包含答辩的问题和答案
java·spring boot·后端
神奇小汤圆2 小时前
京东大模型二面:RAG系统在实际部署中可能面临哪些挑战?
后端
ruxingli2 小时前
GoLang channel管道
开发语言·后端·golang
dovens2 小时前
SpringBoot 集成 Activiti 7 工作流引擎
java·spring boot·后端
_DCG_2 小时前
go第一个工程安装过程与问题汇总
开发语言·后端·golang