MySQL 多表关联查询优化实践和原理解析

news2024/11/17 16:02:55

目录

    • 一、前言
    • 二、表数据准备
    • 三、表关联查询原理和两种算法
      • 3.1、研究关联查询算法必备知识点
      • 3.2、嵌套循环连接 Nested-Loop Join(NLJ) 算法
      • 3.3、基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法
      • 3.4、被驱动表的关联字段没索引为什么要选择使用 BNL 算法而不使用 Nested-Loop Join 呢?
    • 四、多表关联查询优化实践
      • 4.1、使用左连接查询 全部订单列表信息返回订单编号和客户昵称
      • 4.2、使用内连接查询 全部订单列表信息返回订单编号和客户昵称
      • 4.3、使用内连接查询 客户编号`C00000999`全部订单列表信息返回订单编号和客户昵称
    • 五、总结

一、前言

      索引是为了高效查询排好序的数据结构,当表数据量到达一个量级没有对应索引帮助查询耗时会很长,MySQL资源开销也会非常大,对于多表关联查询来说没有对应索引辅助查询资源开销是灾难级的,当然索引也不能随意创建,要做到尽量少的索引解决尽量多的问题,这里会对一些业务场景做索引优化演示,也会讲解多表关联查询的底层原理。

二、表数据准备

这里准备10w条订单数据和1000条用户数据,数据量越大能看到的效果越明显。

  • 订单信息表和数据准备
# 创建订单信息表
DROP TABLE IF EXISTS `order_info`;
CREATE TABLE `order_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '订单ID',
  `order_no` varchar(100)  NOT NULL COMMENT '订单编号',
  `customer_id` bigint(20) NOT NULL COMMENT '客户ID',
  `customer_no` varchar(100) NOT NULL COMMENT '客户编号',
  `goods_id` bigint(20) NOT NULL COMMENT '商品ID',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='订单信息表';

## 创建一个插入数据的存储过程
DROP PROCEDURE IF EXISTS insert_order_procedure;
delimiter;;
CREATE PROCEDURE insert_order_procedure() 
BEGIN
  DECLARE i INT DEFAULT 1;
  DECLARE customer_id BIGINT;
  DECLARE t_error INTEGER DEFAULT 0;
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
  START TRANSACTION;
  WHILE ( i <= 100000 ) DO
    SET customer_id = CEIL(RAND() * 1000);
    INSERT INTO `order_info`(`order_no`,`customer_id`,`customer_no`, `goods_id`, `create_time`) VALUES (CONCAT('ON00000',i), customer_id, CONCAT('C00000',customer_id), CEIL(RAND() * 100), NOW());
    SET i = i + 1;
    
  END WHILE;
  IF t_error=1 THEN
    ROLLBACK;
  ELSE
    COMMIT;
  END IF;
END;;
delimiter;

# 调用存储过程插入数据 我本地插入10w条数据耗时20s
CALL insert_order_procedure();
  • 客户信息表和数据准备
# 创建客户信息表
DROP TABLE IF EXISTS `customer_info`;
CREATE TABLE `customer_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '客户ID',
  `customer_no` varchar(100) DEFAULT NULL COMMENT '客户编号',
  `nick_name` varchar(20) DEFAULT NULL COMMENT '昵称',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='客户信息表';

## 创建一个插入数据的存储过程
DROP PROCEDURE IF EXISTS insert_customer_procedure;
delimiter;;
CREATE PROCEDURE insert_customer_procedure() 
BEGIN
  DECLARE i INT DEFAULT 1;
  DECLARE t_error INTEGER DEFAULT 0;
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET t_error=1;
  START TRANSACTION;
  WHILE ( i <= 1000 ) DO
	  INSERT INTO `customer_info`(`customer_no`,`nick_name`, `age`, `create_time`) VALUES (CONCAT('C00000',i),CONCAT('Kerwin',i), CEIL(RAND() * 100), NOW());
    SET i = i + 1;
  END WHILE;
  IF t_error=1 THEN
    ROLLBACK;
  ELSE
    COMMIT;
  END IF;
END;;
delimiter;

# 调用存储过程插入数据
CALL insert_customer_procedure();

三、表关联查询原理和两种算法

      在MySQL中表关联查询有两种算法,在关联字段有索引时使用的是 嵌套循环连接 Nested-Loop Join(NLJ) 算法,在没有索引时使用的是 基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法,下面会对两种算法做解释。

3.1、研究关联查询算法必备知识点

研究关联查询首先要知道什么是驱动表和什么是被驱动表,MySQL常用三种关联查询分别为左外连接(LEFT JOIN ON)、右外连接(RIGHT JOIN ON)、内连接(INNER JOIN ON),对于这三种关联查询驱动表和被驱动表也是不同的,下面举例说明。

  • 左外连接(LEFT JOIN ON)
EXPLAIN SELECT * FROM order_info t1 LEFT JOIN customer_info t2 ON t1.customer_no=t2.customer_no;

在这里插入图片描述

执行计划中如果id相同那么执行顺序是由上到下,在执行计划里我们可以看到 t1(order_info)在上,t2(customer_info)在下,关联查询中谁在上那么谁就是驱动表,所以 t1(order_info)为驱动表,t2(customer_info)为被驱动表。

  • 右外连接(RIGHT JOIN ON)
EXPLAIN SELECT * FROM order_info t1 RIGHT JOIN customer_info t2 ON t1.customer_no=t2.customer_no;

在这里插入图片描述

执行计划中如果id相同那么执行顺序是由上到下,在执行计划里我们可以看到t2(customer_info)在上, t1(order_info)在下,关联查询中谁在上那么谁就是驱动表,所以 t2(customer_info)为驱动表,t1(order_info)为被驱动表。

  • 内连接(INNER JOIN ON)

    • 查看执行计划SQL
    EXPLAIN SELECT * FROM order_info t1 INNER JOIN customer_info t2 ON t1.customer_no=t2.customer_no;
    
    • 两张表的customer_no字段都没有索引
      在这里插入图片描述
    • 两张表的customer_no字段都有索引
      # 添加索引
      ALTER TABLE `customer_info` ADD INDEX `idx_customerNo`(`customer_no`);
      ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
      
      在这里插入图片描述
    • customer_info表有customer_no字段索引order_info表没有
      # 删除索引
      ALTER TABLE `order_info` DROP INDEX `idx_customerNo`;
      
      在这里插入图片描述
    • order_info表有customer_no字段索引customer_info表没有
      # 删除索引
      ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
      # 添加索引
      ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
      
      在这里插入图片描述
  • 总结
    驱动表和被驱动表的辨认方式就在其执行顺序,在上的是驱动表,在下的是被驱动表,左连接查询那么左边的表一定是驱动表,右连接查询那么右边的表一定是驱动表,内连接会根据表的大小还有是否有索引来选择驱动表和被驱动表,因为customer_info只有1000条数据而order_info表有10w条数据在两张表都没有索引的情况下内连接选择了customer_info做驱动表,在两张表都有索引的情况下会内连接选择小表做驱动表,在一张表有索引一张表没有索引的情况下内连接会选择没有索引的表作为驱动表,原因会在下面说明。

3.2、嵌套循环连接 Nested-Loop Join(NLJ) 算法

       嵌套循环连接算法一次一行循环地从第一张表(称为驱动表)中读取行,在这行数据中取到关联字段,根据关联字段在另一张表(被驱动表)里取出满足条件的行,然后取出两张表的结果合集,嵌套循环连接中被驱动表关联字段一定是有索引,如果没有索引那用的就是基于块的嵌套循环连接算法,下面演示一下。

  • 因为嵌套循环连接需要索引,这里先对order_info表的customer_no创建一个普通索引:
# 如果没有删除customer_info表中的idx_customerNo索引需要先删除
ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
# 添加order_info表索引
ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
  • 查看执行计划
EXPLAIN SELECT * FROM order_info t1 INNER JOIN customer_info t2 ON t1.customer_no=t2.customer_no;

在这里插入图片描述
这里可以看到内连接使用了customer_info作为驱动表,使用order_info作为被驱动表,还使用到了我们刚刚创建的idx_customerNo索引。

  • 上面sql的大致流程如下:
    • 1、从表 t2 中读取一行数据(如果t2表有查询过滤条件的,会从过滤结果里取出一行数据。
    • 2、从第 1 步的数据中,取出关联字段 customer_no,到表 t1 中查找。
    • 3、取出表 t1 中满足条件的行,跟 t2 中获取到的结果合并,作为结果返回给客户端。
    • 4、 重复上面 3 步。

       整个过程会读取 t2 表的所有数据(扫描1000行),然后遍历这每行数据中字段 customer_no 的值,根据 t2 表中 customer_no 的值索引扫描 t1 表中的对应行(扫描1000次 t1 表的索引,因为我们这里是一对多关系1次扫描可能最终扫描 t1 表对应多行完整数据,如果是一对一关系,也就是总共 t1 表也扫描了1000行),为了方便计算假设一个用户编号只能下一个订单因此整个过程扫描了 2000 行。
       如果被驱动表的关联字段没索引,使用NLJ算法性能会比较低(下面有详细解释),MySQL会选择Block Nested-Loop Join算法。

3.3、基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法

基于块的嵌套循环连接算法和嵌套循环连接算法区别就在于被驱动表的关联字段没索引,基于块的嵌套循环连接算法会把驱动表的数据读入到 join_buffer 中,然后扫描被驱动表,把被驱动表每一行取出来跟 join_buffer 中的数据做对比。

  • 先将表中的二级索引全删除
# 删除索引
ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
ALTER TABLE `order_info` DROP INDEX `idx_customerNo`;
  • 查看执行计划
    在这里插入图片描述
    这里可以看到内连接使用了customer_info作为驱动表,使用order_info作为被驱动表,而且在Extra中出现了Using join buffer (Block Nested Loop)说明该关联查询使用的是 BNL 算法。

  • 上面sql的大致流程如下:

    • 1、把 t2 的所有数据放入到 join_buffer 中
    • 2、把表 t1 中每一行取出来,跟 join_buffer 中的数据做对比
    • 3、返回满足 join 条件的数据

       整个过程对表 t1 和 t2 都做了一次全表扫描,因此扫描的总行数为100000(表 t1 的数据总量) + 1000(表 t2 的数据总量) =101000。并且 join_buffer 里的数据是无序的,因此对表 t1 中的每一行,都要做 1000 次判断,所以内存中的判断次数是1000 * 100000= 1 亿次。

       这个例子里表 t2 才 1000 行,要是表 t2 是一个大表,join_buffer 放不下怎么办呢?join_buffer 的大小是由参数 join_buffer_size 设定的,默认值是 256k。如果放不下表 t2 的所有数据话,策略很简单,就是分段放。

       比如 t2 表有1000行记录, join_buffer 一次只能放800行数据,那么执行过程就是先往 join_buffer 里放800行记录,然后从 t1 表里取数据跟 join_buffer 中数据对比得到部分结果,然后清空 join_buffer ,再放入 t2 表剩余200行记录,再次从 t1 表里取数据跟 join_buffer 中数据对比。所以就多扫了一次 t1 表。

3.4、被驱动表的关联字段没索引为什么要选择使用 BNL 算法而不使用 Nested-Loop Join 呢?

       如果上面第二条sql使用 Nested-Loop Join,那么扫描行数为 1000 * 100000 = 1亿次,这个是磁盘扫描。很显然,用BNL磁盘扫描次数少很多,相比于磁盘扫描,BNL的内存计算会快得多。
       因此MySQL对于被驱动表的关联字段没索引的关联查询,一般都会使用 BNL 算法。如果有索引一般选择 NLJ 算法,有索引的情况下 NLJ 算法比 BNL算法性能更高。

四、多表关联查询优化实践

       在前面说明了表关联查询原理和两种算法,其实基本优化思路就已经有了,那就是一定要小表驱动大表,给表关联字段加索引,下面会对一些情况做举例说明。

PS:这里例子使用的MySQL版本为5.7,MySQL8.0连接查询看着是没什么变化但是底层好像做了一些优化,我试了几个例子有索引反而会比没索引慢一点,

4.1、使用左连接查询 全部订单列表信息返回订单编号和客户昵称

# 删除索引
ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
ALTER TABLE `order_info` DROP INDEX `idx_customerNo`;
SELECT t1.order_no,t2.nick_name FROM order_info t1 LEFT JOIN customer_info t2 ON t1.customer_no=t2.customer_no;
  • 无索引情况查询测试
    在这里插入图片描述
    在这里插入图片描述
    使用左连接查询无索引时耗时12.497s,因为使用了左连接所以会已左边的表为驱动表,右连接则会用右边表作为驱动表。

  • 添加order_info表中的customer_no字段索引查询测试

    # 添加索引
    ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    -

    在这里插入图片描述
    添加了order_info表的customer_no字段索引查询耗时和不添加基本一致,也没有使用到创建的索引。

  • 添加customer_info表中的customer_no字段索引查询测试

    ALTER TABLE `customer_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    添加customer_info表中的customer_no字段索引查询耗时0.664s效率有大大提升,这里也看到了被驱动表有使用到索引会使用NLJ算法。

4.2、使用内连接查询 全部订单列表信息返回订单编号和客户昵称

# 删除索引
ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
ALTER TABLE `order_info` DROP INDEX `idx_customerNo`;
SELECT t1.order_no,t2.nick_name FROM order_info t1 INNER JOIN customer_info t2 ON t1.customer_no=t2.customer_no;
  • 无索引情况查询测试
    在这里插入图片描述
    在这里插入图片描述
    MySQL选择了小表customer_info作为驱动表,在没有创建索引时查询耗时12.589s,执行计划中显示使用了BNL算法,下面我们加上索引试一下。

  • 添加order_info表中的customer_no字段索引查询测试

    # 添加索引
    ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    添加上索引后查询耗时0.306s性能有明显提升,MySQL还是选择了customer_info表做驱动表,这里使用了NLJ算法。

  • 添加customer_info表中的customer_no字段索引查询测试

    # 添加索引
    ALTER TABLE `customer_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    customer_info表中的customer_no字段索引查询耗时0.690s性能比不加索引高很多,比在order_info表中加索引性能又差一些,当只有小表有索引时,MySQL也会将小表作为被驱动表,这里大表驱动小表肯定会比上面小表驱动大表性能稍差一些。

4.3、使用内连接查询 客户编号C00000999全部订单列表信息返回订单编号和客户昵称

# 删除索引
ALTER TABLE `customer_info` DROP INDEX `idx_customerNo`;
ALTER TABLE `order_info` DROP INDEX `idx_customerNo`;
SELECT t1.order_no,t2.nick_name FROM order_info t1 LEFT JOIN customer_info t2 ON t1.customer_no=t2.customer_no WHERE t1.customer_no='C00000999';
  • 无索引情况查询测试
    在这里插入图片描述
    在这里插入图片描述
    查询耗时0.078s,在无索引时还是选择的t2表作为驱动表,但是查询时间确是快了很多。

  • 添加order_info表中的customer_no字段索引查询测试

    # 添加索引
    ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    这里查询耗时0.045s快了1倍,而且加上order_info表中的索引后MySQL选择了order_info作为驱动表,MySQL认为我们给了一个条件t1.customer_no=‘C00000999’,在order_info表中符合条件的数据会比较少,小于customer_info中的1000条数据,所以这里采用order_info作为驱动表,并且使用到了加的customer_no索引。

  • 删除order_info表中索引添加customer_info表中的customer_no字段索引查询测试

    # 删除索引
    ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
    # 添加索引
    ALTER TABLE `customer_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    耗时0.066s,比不加索引快一点,这里还是选择了customer_info作为驱动表。

  • 给order_info表和customer_info表中的customer_no字段都添加索引查询测试

    # 添加索引
    ALTER TABLE `customer_info` ADD INDEX `idx_customerNo`(`customer_no`);
    # 添加索引
    ALTER TABLE `order_info` ADD INDEX `idx_customerNo`(`customer_no`);
    

    在这里插入图片描述
    在这里插入图片描述
    耗时0.032s效率又有提升,而且这里两个索引都使用到了,customer_info表因为索引后数据还是比order_info少所有MySQL还是选择了customer_info做驱动表。

五、总结

  • 对于关联sql的优化
    • 关联字段加索引
      • 对于关联字段来说被驱动表最好加上索引,如果使用内连接不确定那张表是被驱动表时最好驱动表和被驱动表都加上。
    • 小表驱动大表
      • 在做左连接或右连接查询的时候如果业务允许一定要用小表驱动大表,或者使用内连接交给where条件去判断业务。
    • where的条件也是要添加对应索引的
      • 两张表关联查询不加条件t1 100w条数据,t2 1000条数据,内连接肯定选择t2做驱动表,但是如果有where条件并且有索引,t1表筛选后只剩10条,t2还是1000条,那么这个时候就会使用到t1做驱动表,查询效率会有所提升。
    • 关于MySQL5.7和MySQL8.0连接查询效率问题
      • 我本地跑了一些连接查询的例子MySQL8.0在有些情况比MySQL5.7的确要快而且是快很多,而且有些情况MySQL8.0没有索引时连接查询也很快,甚至比我加了索引走NLJ算法还快,看了执行计划和MySQL5.7是一样的,不知道是不是因为我本地部署两个版本配置是否有什么区别,MySQL8.0做了很多优化等以后研究明白再来详细说明。

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

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

相关文章

C++_pen_静态与常量

成员 常成员、常对象&#xff08;C推荐使用 const 而不用#define,mutable&#xff09; const 数据成员只在某个对象生存周期内是常量&#xff0c;而对于整个类而言却是可变的&#xff08;static除外&#xff09; 1.常数据成员&#xff08;构造函数初始化表赋值&#xff09; c…

华为云云耀云服务器L实例评测|安装搭建学生成绩管理系统

1.前言概述 华为云耀云服务器L实例是新一代开箱即用、面向中小企业和开发者打造的全新轻量应用云服务器。多种产品规格&#xff0c;满足您对成本、性能及技术创新的诉求。云耀云服务器L实例提供丰富严选的应用镜像&#xff0c;实现应用一键部署&#xff0c;助力客户便捷高效的在…

【重拾C语言】四、循环程序设计典例整理(最大公因数、阶乘求和、正整数翻译、打印字符方阵、斐波那契数列……)

目录 前言 四、循环程序设计 4.3 程序设计实例 4.3.1 求两数最大公因数 4.3.2 阶乘求和 4.3.3 正整数翻译 4.3.4 打印字符方阵 4.3.5 百钱百鸡问题 4.3.6 斐波那契数列 4.3.7 迭代法解方程 前言 ChatGPT C语言是一种通用的、过程式的计算机编程语言&#xff0c;由贝…

SQL与关系数据库基本操作

SQL与关系数据库基本操作 文章目录 第一节 SQL概述一、SQL的发展二、SQL的特点三、SQL的组成 第二节 MySQL预备知识一、MySQL使用基础二、MySQL中的SQL1、常量&#xff08;1&#xff09;字符串常量&#xff08;2&#xff09;数值常量&#xff08;3&#xff09;十六进制常量&…

JAVA学习(3)-全网最详细~

回顾 昨天学了 Java 中的数据类型-整型 int - integer,以及什么是标识符identifier和它的命名规则,什么是保留字(reserved word key word),最后还谈到了Java变量包括局部变量和成员变量(在类内部,方法外部的变量),变量必须要初始化,否则会报错.如果有遗忘或者是感兴趣的小伙伴…

ESLint自动修复代码规范错误

基于 vscode 插件 ESLint 高亮错误&#xff0c;并通过配置 自动 帮助我们修复错误 在设置中 settings.json添加这段代码就自动修复错误 // 当保存的时候&#xff0c;eslint自动帮我们修复错误 "editor.codeActionsOnSave": { "source.fixAll": true }, /…

免费app签名分发平台应用cdn分发平台为什么会免费?商业分析他的盈利模式

近年来&#xff0c;随着移动应用的迅速发展&#xff0c;免费app签名分发平台和应用CDN分发平台日益受到开发者和用户的关注。本报告旨在分析这些平台的商业模式&#xff0c;探讨其利润点、营销点以及所采取的优势。 一、商业模式分析&#xff1a; 广告收入&#xff1a; 免费a…

Hive【Hive(五)函数-高级聚合函数、炸裂函数】

高级聚合函数 多进一出&#xff08;多行输入&#xff0c;一个输出&#xff09; 普通聚合函数&#xff1a;count、sum ... 1&#xff09;collect_list&#xff08;&#xff09;&#xff1a;收集并形成 list 集合&#xff0c;结果不去重 select sex,collect_list(job) from e…

机器学习笔记(二)

过拟合 如下图左边,模型出现了过拟合现象 为了解决过拟合现象, 其中一个做法是多收集数据,如右图。 第二种做法是减少模型的特征数量,即x 第三种做法是正则化 正则化就是减少x前面的参数 w的数值, 不用消除x 正则化的梯度下降如下, 因为只是缩小了w的值,而 b的值保持不变 …

项目测试练习

项目背景项目功能测试计划Bug总结升级自动化测试正常登录流程 项目背景 1&#xff1a;博客之站系统是采用前后端分离的方式来实现&#xff1b;使用MySQL、Redis数据库储存相关数据&#xff1b;同时部署到云服务器上。 2&#xff1a;包含注册页、登录页、博客列表页、个人列表页…

vs2015 安装插件

大部分插件可以在这个网页下载到 All categories Extensions - Visual Studio Marketplace 对于一些安装报错的插件&#xff0c;一般都是因为插件的版本与当前vs版本不兼容&#xff0c;解决办法&#xff08;以插件Viasfora为例&#xff09;&#xff1a; 从最近的往下逐个版本试…

“入门C++编程需要多长时间?如何高效学习?“

文章目录 每日一句正能量前言一、c 发展方向二、学c语言编程难吗&#xff1f;三、多久能学会编程&#xff1f;四、“浸泡”理论五、C语言特有特性六、学习方式后记 每日一句正能量 低头要有勇气&#xff0c;抬头要有底气。做人要能屈能伸&#xff0c;顺景时不嚣张&#xff0c;逆…

仿真调试说明——摘抄龙芯杯官方文件

1.仿真调试说明 你需要具备以下知识&#xff1a; 仿真工具的使用&#xff0c;比如Vivado的XsimVerilog的基本语法 通过本文的学习&#xff0c;你将获得&#xff1a;各类仿真错误排查的方法CPU逻辑出错的调试指导Verilog 运算符的优先级 1.1 调试指导思想概述 全局上的调试原…

ChainForge:衡量Prompt性能和模型稳健性的GUI工具包

ChainForge是一个用于构建评估逻辑来衡量模型选择&#xff0c;提示模板和执行生成过程的GUI工具包。ChainForge可以安装在本地&#xff0c;也可以从chrome浏览器运行。 ChainForge可以通过聊天节点对多个对话可以使用不同的llm并行运行。可以对聊天消息进行模板化&#xff0c;并…

systrace/perfetto抓取方式分享

背景 近来有一些同学反馈性能分析&#xff0c;现在大部分都是其实已经开始使用perfetto了&#xff0c;连sdk上都已经找不到哦systrace相关工具&#xff0c;让马哥可以分享一些这个相关内容&#xff0c;其实以前企业里面那时候大部分都是使用老版本systrace的&#xff0c;相比新…

量化交易全流程(六)

本节目录 多因子风险模型 自从股票市场产生以来&#xff0c;大量的学者、业界人员都在研究股票的价格波动究竟是由什么决定的。一个明显的事实是&#xff0c;股票的价格波动一定是由多种因素决定的&#xff0c;比如大盘因素、市值因素和行业因素。对于大盘因素&#xff0c;股…

【Linux】Linux常用命令—文件管理(上)

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

Mysql内置函数、复合查询和内外连笔记

目录 一、mysql内置函数 1.1.日期函数 1.2.字符串函数 1.3.数学函数 1.4.其他函数 二、复合查询 2.2 自连接 2.3 子查询 2.3.1单行自查询 2.3.2 多行子查询 2.3.3 多列子查询 2.3.4在from子句中使用子查询 2.3.5合并查询 三、表的内连和外连 3.1内连接 3.2外连接…

KNN算法与SVM支持向量机

KNN算法 KNN算法就是把要分类的对象&#xff08;例如一个特征向量&#xff09;与训练集中已知类标记的所有对象进行对比&#xff0c;并由K近邻对分类对象进行判断为那个类别。这种方法的效果好&#xff0c;但是也有弊端&#xff0c;与K-means聚类算法一样&#xff0c;需要先预…

【微服务】springboot整合neo4j使用详解

一、前言 在上一篇我们详细了解了neo4j的使用&#xff0c;从搭建到相关的语法操作&#xff0c;本篇紧接着之前的内容&#xff0c;来详细聊聊如何在springboot应用中集成和使用neo4j。 二、Spring Data Neo4j 和很多其他的中间件类似&#xff0c;都提供了类似jpa的方式与sprin…