当前位置: 首页 > news >正文

MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

Mysql实战-为什么索引要建立在被驱动表上

前面我们讲解了B+Tree的索引结构,也详细讲解下 left Join的底层驱动表 选择原理,那么今天我们来看看到底如何用以及如何建立索引和索引优化

开始之前我们先提一个问题, 为什么索引要建立在被驱动表上 ?

文章目录

      • Mysql实战-为什么索引要建立在被驱动表上
        • 1.建表及测试数据
        • 2. 不用连接查询 笛卡尔积
        • 3.带条件的查询过程即被驱动表的查询过程

1.建表及测试数据

我们先创建两个表 test_user 和 test_order 这两个表作为我们的测试表及测试数据

  • test_user 5条数据, 索引只有主键id
  • test_order 5条数据,索引同样也只有主键id
#创建表 test_user
CREATE TABLE `test_user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`id_card` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '身份证ID',`user_name` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '用户名字',`age` int DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`),KEY `idx_age` (`age`),KEY `idx_name` (`user_name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表'
#创建表 test_order
CREATE TABLE `test_order` (`id` int NOT NULL AUTO_INCREMENT,`order_name` varchar(32) NOT NULL DEFAULT '',`user_name` varchar(32) NOT NULL,`pay` int NOT NULL DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表'

插入数据

#插入 user 用户数据
INSERT INTO `test`.`test_user` (`id`, `id_card`, `user_name`, `age`) VALUES (1, '11', 'aa', 10);
INSERT INTO `test`.`test_user` (`id`, `id_card`, `user_name`, `age`) VALUES (2, '22', 'bb', 20);
INSERT INTO `test`.`test_user` (`id`, `id_card`, `user_name`, `age`) VALUES (3, '33', 'cc', 30);
INSERT INTO `test`.`test_user` (`id`, `id_card`, `user_name`, `age`) VALUES (4, '44', 'dd', 40);
INSERT INTO `test`.`test_user` (`id`, `id_card`, `user_name`, `age`) VALUES (5, '55', 'ee', 50);#插入 order 订单数据
INSERT INTO `test`.`test_order` (`id`, `order_name`, `user_name`, `pay`) VALUES (1, '衣服', 'aa', 100);
INSERT INTO `test`.`test_order` (`id`, `order_name`, `user_name`, `pay`) VALUES (2, '鞋子', 'bb', 200);
INSERT INTO `test`.`test_order` (`id`, `order_name`, `user_name`, `pay`) VALUES (3, '电视', 'cc', 300);
INSERT INTO `test`.`test_order` (`id`, `order_name`, `user_name`, `pay`) VALUES (4, '零食', 'cc', 400);
INSERT INTO `test`.`test_order` (`id`, `order_name`, `user_name`, `pay`) VALUES (5, '衣服', 'cc', 500);

查询结果
在这里插入图片描述

2. 不用连接查询 笛卡尔积

我们先不用 join语句, 直接查询2个表,看下效果

#直接查询2个表
select * from test_user,test_order;

得到的解雇i就是 笛卡尔积

  • user表中的每一条记录,都与order表的一条记录形成组合
  • user中有5条数据,order表中也有5条数据
  • user 的 第一条,分别和 order 5条对应
  • 从而俩个表连接后就有 5 * 5 =25条记录

查询结果笛卡尔积, 25条结果
在这里插入图片描述

3.带条件的查询过程即被驱动表的查询过程

上面我们见识到了 如果没有任何条件,我们连接的2个表会形成笛卡尔积,数量膨胀很大,所以 我们在连接的时候一般都需要过滤条件,我们加一些条件,看下效果

#带条件的 笛卡尔积查询
select * from test_user,test_order where test_user.id > 1 and test_user.id = test_order.id and test_order.pay  >200 ;

执行结果如下, 只有3条
在这里插入图片描述

查询条件如下

  • test_user.id > 1
  • test_user.id = test_order.id
  • test_order.pay > 200
    • 首先 id > 1, 就只剩下 user2,3,4,5
    • 然后test_user.id = test.order.id 这样子就会把很多笛卡尔积 全部去掉, 只保留 两个表 id相同的记录, 还是user的 2,3,4,5
    • 最后还有个 pay>200, 这样就通过掉了 user=2这一条 pay=200, 只保留 3,4,5
    • 也就是我们要的查询结果

我们来分析下执行过程

  1. 确定驱动表,我们先假设 user表是驱动表,然后分析下执行过程
  2. 根据查询条件 test_user.id >1 ,如果 id不是主键, 而且也没索引, 那就是全表扫描ALL, 找到4条记录 user_id = 2,3,4,5
  3. 根据上面驱动表的数据(前面假设是 user), 然后从被驱动表 test_order中寻找匹配的记录,也就是 user_id =2,3,4,5 和 test_user.id = test_order.id匹配的记录
  4. 此时开始查询 test_order,当匹配第一条 test_user.id = 2时, 简化查询条件 test_user.id = test_order.id 就变成了 test_order.id = 2 并且还剩余 一个查询条件 test_order.pay > 200
  5. 所以 test_order 的表就变成了单表查询, 两个查询条件 test_order.id = 2 and test_order.pay >200, 执行test_order的单表查询,查询结果不满足,因为 test_order.id =2 的 pay=200,不pay >200的条件, 本次结束, 继续
  6. 开始下一次 当 user_id =3时, test_order的单表查询变成了 test_order.id =3 and test_order.pay > 200,进行查询, 满足条件,返回结果
  7. 依次类推,直到 user_id 的记录3,4,5匹配完毕 ,最终得到 3条记录
  8. 这就是查询过程

从上面的过程中,我们可以知道,驱动表 只访问了一次
但是被驱动表 要匹配记录,需要不停的去查询,匹配,被动表访问了很多很多次
所以 这就是为什么要把索引建立在被驱动表上的原因


至此,我们通过Mysql的执行查询过程,分析了解到了索引要建立在被驱动表上的原理,这对于我们后期进行SQL分析,有着重要的作用

相关文章:

MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

Mysql实战-为什么索引要建立在被驱动表上 前面我们讲解了BTree的索引结构,也详细讲解下 left Join的底层驱动表 选择原理,那么今天我们来看看到底如何用以及如何建立索引和索引优化 开始之前我们先提一个问题, 为什么索引要建立在被驱动表上…...

C语言,数据结构指针,结构构体操作符 •,->,*的区别,看这篇就够了

在朋友们学习指针和数据结构这一章的时候,对各种操作符云里雾里。当你看到这么文章之后你就会明白了。 一 • 和 ->运算符 • 运算符:是结构变量访问结构体成员时用的操作符 -> 运算符:这是结构体指针访问结构体成员时调用的运算符。 …...

axios 多个baseURL配置、实现不同前缀代理到不同的服务器的几种方式

前言: 在开发中,有可能遇到每部分的功能的需要调用另一台服务器的地址。这个时候就需要设置不同的请求前缀首先代理到不同的服务器地址。 一、axios封装实例以及代理:(不是完整的封装实例,重点在于baseURL的区别) 文件路径&…...

Diango项目-简易个人博客项目

项目实现功能 在admin后台自定义添加上传文档。对展示在首页的文章分页显示。在首页点击文章的阅读全文按钮可进入该文章全文详情页进行浏览。对文章实现了内容分类何以发布时间进行归档分类。使用django的whoose搜索引擎对全文实现内容的搜索。 项目涉及技术 Mysql Djan…...

思维训练3

题目描述1 Problem - A - Codeforces 题目分析 样例1解释: 对于此题,我们采用贪心的想法,从1到n块数越少越好,故刚好符合最少的块数即可,由于第1块与第n块是我们必须要走的路,所以我们可以根据这两块砖的…...

初识FFmpeg

前言 无意间见到群里的小伙伴展示视频工具。功能比较多,包括视频编码修改,画质处理,比例处理、名称提取,剪辑、标题拆解。因此开始了FFmpeg学习。以下摘自百度百科的解释。 FFmpeg是一套可以用来记录、转换数字音频、视频&#xf…...

分布式多主关系数据库的底线业务优势

当今的应用程序(包括企业应用程序)需要始终开启且始终可用,并且通常必须为全球用户提供服务,这些用户无论身在何处都希望获得几乎即时的响应时间。 应对这些挑战不仅仅意味着让用户更满意:每个能够解决低延迟和超高可…...

JMM讲解

一:为什么要有JMM,它为什么出现? CPU的运行并不是直接操作内存而是先把内存里面的数据读到缓存,而内存的读和写操作的时候会造成不一致的问题。JVM规范中试图定义一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异&…...

小程序获取头像和昵称的思路

小程序获取头像和昵称的基本方法是调用小程序自带的API wx.getUserProfile(),这也是小程序官方目前最推荐的做法。成功获取用户名头像之后,小程序允许保存调用的结果,以便下一次打开页面的时候自动显示头像和名字。保存用户名和头像并不是保存…...

关于docker网络实践中遇到的问题

1.禁用docker自动修改iptables规则 查看docker.service文件/usr/lib/systemd/system/docker.service 默认在宿主机部署容器,映射了端口的话,docker能自己修改iptables规则,把这些端口暴露到公网。 如果要求这些端口不能暴露到公网&#xf…...

C#完成XML文档节点的自动计算功能

一个项目涉及XML文档中节点的自动计算,就是XML文档的每个节点都参与运算,要求: ⑴如果节点有计算公式则按照计算公式进行; ⑵如果节点没有计算公式则该节点的值就是所有子节点的值之和; ⑶节点有4种类型,计…...

体验SOLIDWORKS旋转反侧切除增强 硕迪科技

大家在设计中经常使用的旋转切除命令在solidworks2024版本中迎来了新的增强,添加了旋转反侧切除选项。在设计过程中不必修改复杂的草图即可切除掉我们不需要的部分。使设计工作更加方便快捷。 打开零部件后,点击键盘上的S键并输入旋转切除以搜索该命令&a…...

分布式ID系统设计(3)

分布式ID系统设计第三集 id-service-SnowFlake方案 第二集说了id-service-Segment-DB可以生成趋势递增的ID,但是ID号是可以计算的。不太适用于一些订单ID生成的场景。因为存在数据暴露的风险 比如我可以对比两天的订单ID号来大致计算出公司一天的订单量。这个有点危险。 所以…...

工作备忘录【微信】

这工作备忘录【微信】里写自定义目录标题 unionid获取用户基本信息无 unionid EasyWeChat"overtrue/wechat": "^4.6" 与 "overtrue/wechat": "~3.1" 使用方式有异 unionid 微信 unionid 有关备忘录 获取用户基本信息无 unionid htt…...

Window下SRS服务器的搭建

---2023.7.23 准备材料 srs下载:GitHub - ossrs/srs at 3.0release 目前srs release到5.0版本。 srs官方文档:Introduction | SRS (ossrs.net) Docker下载:Download Docker Desktop | Docker 进入docker官网选择window版本直接下载。由…...

Canvas绘制简易雨滴碰撞效果

实现会动的图形&#xff0c;向下播放多张静态的图片。一秒内要大于屏幕刷新的帧数(60) 也就是每隔1/60s执行一次函数在每次绘制的正方形上添加一个背景色为白色蒙板。 效果图 源代码 <!DOCTYPE html> <html lang"en"><head><meta charset"…...

【五、http】go的http的信息提交

一、post提交的几种 form表单json文件 1、提交表单 //http的postfunc requstPost(){params : make(url.Values)params.Set("name", "kaiyue")params.Set("age", "18")formDataStr : []byte(params.Encode())formDataByte : bytes.N…...

第六讲:VBA与ACCESS的ADO连接中,所涉及的对象

《VBA数据库解决方案》教程&#xff08;10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法和实…...

【计算机网络】同源策略及跨域问题

1. 同源策略 同源策略是一套浏览器安全机制&#xff0c;当一个源的文档和脚本&#xff0c;与另一个源的资源进行通信时&#xff0c;同源策略就会对这个通信做出不同程度的限制。 同源策略对 同源资源 放行&#xff0c;对 异源资源 限制。因此限制造成的开发问题&#xff0c;称…...

uniapp在APP端使用swiper进行页面不卡顿滑动

uniapp在APP端使用swiper进行页面会卡顿&#xff0c;主要是渲染的数据有点多&#xff0c;这里只渲染三个数据就不好那么卡顿了&#xff0c;每次滑动后更新数据 <view><swiper change"changePoint" circular :disable-touch"disableTouch"><…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!

本文介绍了一种名为AnomalyAny的创新框架&#xff0c;该方法利用Stable Diffusion的强大生成能力&#xff0c;仅需单个正常样本和文本描述&#xff0c;即可生成逼真且多样化的异常样本&#xff0c;有效解决了视觉异常检测中异常样本稀缺的难题&#xff0c;为工业质检、医疗影像…...