MYSQL高级之关联查询优化

建表

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ATECLOUD云测试平台新能源电机测试系统:高效、可扩展的测试利器

随着全球对环境保护的日益重视,新能源的发展越来越受到关注。电动汽车作为新能源领域的重要组成部分,其性能和质量对于消费者来说至关重要。为了确保电动汽车的性能和质量,测试系统平台解决方案变得越来越重要。本文将介绍一种基于ATECLOUD智…

基于SSM的网辩平台的设计与实现

摘 要 线上作为当前信息的重要传播形式之一,线上辩论系统具有显著的方便性,是人类快捷了解辩论信息、资讯等相关途径。但在新时期特殊背景下,随着网辩的进一步优化,辩论赛结合网络平台融合创新强度也随之增强。本文就网辩平台进…

Linux操作系统相关介绍

目录 一、认识Linux 二、Linux特点总结 三、Linux版本 (1)Linux内核版 (2)Linux发行版 一、认识Linux • 1991年,芬兰的一名大学生Linus Torvalds开发了linux内核 • Linux是一种开放源代码的、自由的、免费的类…

【Linux】线程互斥

文章目录 1. 背景概念多个线程对全局变量做-- 操作 2. 证明全局变量做修改时,在多线程并发访问会出问题3. 锁的使用pthread_mutex_initpthread_metux_destroypthread_mutex_lock 与 pthread_mutex_unlock具体操作实现设置为全局锁 设置为局部锁 4. 互斥锁细节问题5.…

DevOps该怎么做?

年初在家待了一段时间看了两本书收获还是挺多的. 这些年一直忙于项目, 经历了软件项目的每个阶段, 多多少少知道每个阶段是个什么, 会做哪些事情浮于表面, 没有深入去思考每个阶段背后的理论基础, 最佳实践和落地工具. 某天leader说你书看完了, 只有笔记没有总结, 你就写个总结…

ifconfig工具与驱动交互解析(ioctl)

Linux ifconfig(network interfaces configuring) Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态,或是显示目前的设置。同netstat一样,ifconfig源码也位于net-tools中。源码位于net-tools工具包中&am…

【LeetCode】HOT 100(2)

题单介绍: 精选 100 道力扣(LeetCode)上最热门的题目,适合初识算法与数据结构的新手和想要在短时间内高效提升的人,熟练掌握这 100 道题,你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

软件测试测试环境搭建很难?一天学会这份测试环境搭建教程

如何搭建测试环境?这既是一道高频面试题,又是困扰很多小伙伴的难题。因为你在网上找到的大多数教程,乃至在一些培训机构的课程,都不会有详细的说明。 你能找到的大多数项目,是在本机电脑环境搭建环境,或是…

【单目标优化算法】孔雀优化算法(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

MySQL — 主从复制介绍

文章目录 主从复制一、概述二、原理三、 搭建主从复制结构3.1 服务器准备3.2 主库配置3.3 从库配置 主从复制 一、概述 ​ 主从复制是指将主数据库的DDL和DML操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做)…

1. TensorRT量化的定义及意义

前言 手写AI推出的全新TensorRT模型量化课程,链接:TensorRT下的模型量化。 课程大纲如下: 1. 量化的定义及意义 1.1 什么是量化? 定义 量化(Quantization)是指将高精度浮点数(如float32)表示为低精度整数(如int8)的过程&…

如何运用R语言进行Meta分析在【文献计量分析、贝叶斯、机器学习等】多技术的融合

Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…

华为OD机试真题 Java 实现【高矮个子排队】【2023Q2 100分】,附详细解题思路

一、题目描述 现在有一队小朋友,他们高矮不同,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。 我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,每一个“高”位置的小朋友要比相邻的位置高…

【配电网重构】基于改进二进制粒子群算法的配电网重构研究(Matlab代码实现

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

批量剪辑视频工具源码开发搭建分享

搭建步骤 1. 首先需要根据自身产品确定视频类型及需要实现的视频效果 2. 根据预期视频效果选择视频上传模式,并将视频素材进行上传 3. 添加音频、字幕,标题等与素材进行组合。 4. 设置投放计划,包括:视频标题、视频话题等 5.…

dom阶段实战内容

window定时器方法 ◼ 目前有两种方式可以实现:  setTimeout 允许我们将函数推迟到一段时间间隔之后再执行。  setInterval 允许我们重复运行一个函数,从一段时间间隔之后开始运行,之后以该时间间隔连续重复运行该函数。 ◼ 并且通常情况…

周赛347(模拟、思维题、动态规划+优化)

文章目录 周赛347[2710. 移除字符串中的尾随零](https://leetcode.cn/problems/remove-trailing-zeros-from-a-string/)模拟 [2711. 对角线上不同值的数量差](https://leetcode.cn/problems/difference-of-number-of-distinct-values-on-diagonals/)模拟 [2712. 使所有字符相等…

什么是分布式事务?

什么是分布式事务? 分布式对应的是单体架构,互联网早起单体架构是非常流行的,好像是一个家族企业,大家在一个家里劳作,单体架构如下图: 但是随着业务的复杂度提高,大家族人手不够,…

如何使用 Python Nornir 实现基于 CLI 的网络自动化?

在现代网络环境中,网络自动化已成为管理和配置网络设备的重要工具。Python Nornir 是一个强大的自动化框架,它提供了一个简单而灵活的方式来执行网络自动化任务。本文将详细介绍如何使用 Python Nornir 实现基于 CLI 的网络自动化。 1. Python Nornir 概…

view的常用属性和方法介绍(arcgis for javascript)

ArcGIS for JavaScript中的视图(view)是一个地图实例类,用于管理地图的显示区域、符号和标注等。通过视图类,可以实现以下功能: 显示地图:将地图显示在Web页面上。 缩放:缩放视图到指定的级别。…