MYSQL高级之关联查询优化

news2024/10/7 4:31:16

建表

CREATE TABLE IF NOT EXISTS `class` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `book` (
`bookid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`card` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`bookid`)
);
 
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO class(card) VALUES(FLOOR(1 + (RAND() * 20)));
 
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));
INSERT INTO book(card) VALUES(FLOOR(1 + (RAND() * 20)));

题目

查询card对应的book的所有的信息

查询一

EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;

在这里插入图片描述
我们可以看到type中都是all,我们优化中最主要关注的就是type,也就是说他是全表扫描,我们对他进行优化

查询二

添加索引

ALTER TABLE `book` ADD INDEX Y ( `card`);

再次执行查询语句

EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;

在这里插入图片描述

  • 我们会发现表book查询type变为了ref,rows的变化也非常明显
  • left join 条件用于确定如何从右表搜索行,左边一定有,所以右边是我们的关键点,一定需要建立索引
  • 假设我们给左表新建索引,那么查询如下
# 删除原先的索引
DROP INDEX Y ON book;
# 新建索引
ALTER TABLE class ADD INDEX X (card);
# 查询
EXPLAIN SELECT * FROM class LEFT JOIN book ON class.card = book.card;

我们会发现他优化的并不明显

在这里插入图片描述

总结

  1. 保证被驱动表的join字段已经被索引
  2. left join时,选择小表作为驱动表,大表作为被驱动表。
  3. inner join的时候mysql自己会帮你把最小结果集的表选为驱动表
  4. 子查询尽量不要放在被驱动表,有可能使用不到索引
    1. 如果必须用到子查询,可将子查询设置为驱动表,因为驱动表的type肯定是all,而子查询返回的结果表没有索引,必定也是all,例子如下
SELECT a.name ,bc.name FROM t_emp a LEFT JOIN
         (SELECT b.id , c.name FROM t_dept b
         INNER JOIN t_emp c ON b.ceo = c.id)bc 
         ON bc.id = a.deptid.
  1. 上面代码用到了子查询,其中临时表bc必然没有索引,那么他就会进行全表的扫描
  2. 可以使用两个left join来进行优化,如下
SELECT a.name , c.name FROM t_emp a
    LEFT OUTER JOIN t_dept b ON a.deptid = b.id
    LEFT OUTER JOIN t_emp c ON b.ceo=c.id

这样,所有的条件都会用到索引

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

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

相关文章

vue router实现路由跳转方法

今天在学习 vue的过程中,看到了 vue的 router,用它来实现路由跳转,非常方便,于是就尝试了一下。效果还不错。 首先我们需要了解一个概念: Router。 Router是一个接口,它提供了一个接口让我们可以从一个地方…

Flutter 笔记 | Flutter 核心原理(二)关键类和启动流程

Widget、Element、BuildContext 和 RenderObject Widget Widget关键类及其子类继承关系如图所示: 其中,Widget是Widget Tree所有节点的基类。Widget的子类主要分为3类: 第1类是RenderObjectWidget的子类,具体来说又分为SingleCh…

08. 算法之递归算法

前言 递归,字面意思是递出去,拿回来,通过不断递过去,拿回来的过程,将每次调用结果保存起来,最后实现循环调用。递归在某些情况下会极大降低我们编程的复杂度。是软件开发工程师一定要掌握的技能。 1. 概念…

Linux—实操篇:vi和vim编辑器

1.vi和vim基本介绍 Linux系统会内置vi文本编辑器 vim具有程序编写的能力,可以看做是vi的增强版本,被程序员广泛使用 2、vi和vim常用的三种模式 2.1、正常模式 以vim打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中,你可…

溯源取证 - 流量分析 中等难度

使用工具: Brim 链接: https://www.brimdata.io/download/ Networkminer 链接: https://www.netresec.com/?pageNetworkMiner Wireshark Strings ida pro 知识点: 通过本篇文章,学习ssh协议特点、学习流量导出文件、学习简单的逆向分析、…

卫星定位北斗芯片AT6558一款高性能BDS/GNSS多模卫星导航接收机SOC单芯片

1 芯片简介 AT6558R是一款高性能BDS/GNSS多模卫星导航接收机SOC单芯片,片上集成射频前端, 数字基带处理器,32位的RISCCPU,电源管理功能。 芯片支持多种卫星导航系统,包括中国的北斗卫星导航系统BDS,美国的GPS,俄罗斯 的…

Mysql DDL执行方式-pt-osc介绍 | 京东云技术团队

1 引言 大家好,接着上次和大家一起学习了《MySQL DDL执行方式-Online DDL介绍》,那么今天接着和大家一起学习另一种MySQL DDL执行方式之pt-soc。 在MySQL使用过程中,根据业务的需求对表结构进行变更是个普遍的运维操作,这些称为…

elasticsearch分词,排序,分页,高亮简单示例

目录 1. 创建ES实体2. 创建查询实体3. 查询方法实现3.1 总体代码3.2 构建查询条件3.2.1 关键词分词 3.3 高亮处理4.总体查询代码 记,写一个简单的es分词demo,es版本6.8.12 如果使用es7有些方法可能会有所改变,请参考7的文档 es安装教程:http:…

SUSE系统上安装HANA

一:安装SUSE操作系统 1.1 准备安装镜像 SLE-15-SP1-安装程序-DVD-x86_64-GM-DVD1 SLE-15-SP1-软件包-x86_64-GM-DVD1 SAP HANA安装文件 IMDB_SERVER20_032_0-80002031.SAR 1.2 引导系统 1.3 选择要安装的产品 SUSE Linux Enterprise Server for SAP Applications 15 SP…

Stable Diffusion教程(5) - 文生图教程

配套视频教程: https://v.douyin.com/UyHNfYG/ 文生图界面标注如下 1 提示词和反向提示词 提示词内输入的东西就是你想要画的东西,反向提示词内输入的就是你不想要画的东西 提示框内只能输入英文,所有符号都要使用英文半角,词语…

企业级信息系统开发讲课笔记4.5 掌握Spring Boot多环境配置

文章目录 零、学习目标一、项目进行多环境配置的必要性二、使用Profile文件进行多环境配置(一)创建Spring Boot项目(二)创建多环境配置文件1、全局配置文件改名2、模拟开发环境3、模拟测试环境4、模拟生产环境 (三&…

Unity基础 音频组件以及音频播放

在游戏开发中,声音是一个重要的环节。Unity中的声音组件可以帮助开发者轻松地控制游戏中音频的播放、音量、循环等属性,从而实现更好的游戏体验。本文将详细介绍Unity声音组件的相关概念和技术,以及其在游戏、影视等领域的广泛应用和发展前景…

银行联行号-联行号api接口-联行号数据源

接口地址: https://登录后显示/api/180/348(支持:http/https) 数据源:https://www.wapi.cn/source/8.html 网站地址:https://www.wapi.cn 返回格式:json,xml 请求方式:GET,POST 请求说明: 银行联行号-联行…

数据集:T-Drive(北京出租车轨迹数据)

1 数据来源 T-Drive trajectory data sample - Microsoft Research 2 数据介绍 数据集包含了2008年2月2日至2月8日期间在北京市内的10,357辆出租车的GPS轨迹。总共包含约1500万个GPS点,轨迹总里程达到了900万公里。 图1显示了两个连续点之间的时间间隔和距离间隔…

Apache 配置和应用

目录 构建虚拟 Web 主机 Options指令解释 Options指令常用选项 AllowOverride指令解释: 地址限制策略: httpd服务支持的虚拟主机类型包括以下三种: 基于域名的虚拟主机 1.为虚拟主机提供域名解析 2.为虚拟主机准备网页文档 3.添加虚拟…

【服务器】springboot实现HTTP服务监听

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…

Mysql 异常,“Cause: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException”

Cause: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request 简言:这种异常从字面翻译过来:mysql 请求链接超时,具体超时是什么原因导致的,可以根据情况分析下。 异常详…

【黄啊码】PHP商城中的积分任务系统实现

大家好,我是黄啊码,前几天有位小伙伴问我,商城中的任务系统是怎么实现的? 积分作为一种营销手段,被广泛运用于线上/线下的产品中,以此来增加用户对于产品的粘性。比如天猫积分可以用来兑换商品&#xff0c…

uni-app通过vue.config.js在项目中配置跨域代理

其实这个 如果你用nginx去配肯定再好不过 不过 一般大家也都不想把开发环境弄那么复杂 最好还是在项目中配置 那么 我们选择项目跟目录右键 选择 使用命令行窗口打开所在目录 在新弹出的命令行中引入依赖 npm install http-proxy-middleware --save-dev然后我们的依赖就进来…

【通信接口】CAN总线协议

目录 一、什么是CAN 1、CAN 的概念 2、节点构成(CAN 总线通信模型) 3、差分信号(电平特性) 4、CAN 总线的特点 二、CAN 总线协议的通信过程 1、发送过程 2、接收过程 3、概括 三、CAN 通信帧的分类 一、什么是CAN 1、C…