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=utf8

插入数据

#插入 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分析,有着重要的作用

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

选择适合制造业的企业邮箱平台

自2010年成立以来,J公司已从一家小型有限责任公司发展成为全球领先的工业内窥镜研发、生产和销售企业。公司的产品制造采用国际先进技术和一流生产工艺,专业为客户提供定制解决方案,产品已广泛应用于锅检特检、机械制造、发电、石油、燃气、化…

一款成熟的文件外发审计管控系统,应该具备哪些价值?

在信息化高速发展的时代,电子文件泄密事件层出不穷,比如文本文档、图像、音频、视频、电子表格等,都是日常会接触到的文件类型。像制造业企业,会有比较多的上下游协作交流,外发的电子文档以明文的形式提供给合作伙伴&a…

当女朋友要求你用Python画一个粉粉的Hello Kitty的时候

先看效果图 完整代码 import math import turtle as t# 计算长度、角度 t1:画笔对象 r:半径 angle:扇形(圆形)的角度 def myarc(t1, r, angle):arc_length 2 * math.pi * r * angle / 360 # angle角度的扇形的弧长n int(arc_length / 3) 1 # 线段…

【K8S】二进制安装

常见的K8S安装部署方式 ●Minikube Minikube是一个工具,可以在本地快速运行一个单节点微型K8S,仅用于学习、预览K8S的一些特性使用。 部署地址:https://kubernetes.io/docs/setup/minikube ●Kubeadm☆ Kubeadm也是一个工具,提…

编程实例:操作简单物流快运单据打印软件,可以定制打印格式

编程实例:操作简单物流快运单据打印软件,可以定制打印格式 打印格式可以定制。 编程系统化课程总目录及明细,零基础学编程视频教程,点击进入了解详情。 https://blog.csdn.net/qq_29129627/article/details/134073098?spm1001.20…

前端搭建名言生成器(内附源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ JS是什么?✨ 名言生成器✨ 页面搭建✨ 功能实现 ✨ 写在前面 在上周我们通过HTML、CSS实现了一个简单的‘我的相册‘页面的搭建,很多伙伴呢跟我说难道前端就只能做一些页面搭建的工作吗&#xff1…

Kubernetes包管理工具Helm简介及使用

文章目录 前言技术积累什么是HelmHelm的核心概念Helm可以解决哪些痛点Helm中文官方文档 Helm安装Helm安装nginx用例写在最后 前言 大家都知道K8S是云原生devops的一大利器,可以直接让我们的中间件、应用服务直接运行在云端,让我们可以只关心自身的业务功…

JavaScript从入门到精通系列第二十六篇:详解JavaScript中的Math对象

大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥连接:孙哥个人主页 作者简介:一个颜值99分,只比孙哥差一点的程序员 本专栏简介:话不多说,让我们一起干翻J…

opencv c++ canny 实现 以及与halcon canny的对比

Opencv和C实现canny边缘检测_opencv边缘增强-CSDN博客 一、canny实现步骤 1、图像必须是单通道的,也就是说必须是灰度图像 2、图像进行高斯滤波,去掉噪点 3、sobel 算子过程的实现,计算x y方向 、梯度(用不到,但是…

vim

简介 vim是一款多模式的文本编辑器,vim里面还有很多子命令,来进行代码的编写操作 常用模式图 命令模式 光标移动 shif $ 光标定义到当前行的最右侧结尾 shift ^ 光标定义到当前行的最左侧开头 shift g 光标定位到文本最末尾…

如何有效使用蜂邮EDM和vba批量发送邮件?

蜂邮EDM和vba批量发送邮件的方法?怎么使用蜂邮EDM和vba代码群发电子邮件? 批量发送邮件已经成为一种不可或缺的沟通方式。蜂邮EDM和VBA是两个功能强大的工具,可以帮助您在邮件营销和业务通信中实现高效的批量发送邮件操作。接下来将介绍如何…

Revo Uninstaller Pro:终极卸载工具,彻底清除电脑痕迹

你是否曾为无法彻底卸载软件,残留大量无用文件而感到烦恼?是否曾因恶意软件难以清除,导致电脑运行缓慢?这些问题,Revo Uninstaller Pro都能帮你解决。 Revo Uninstaller Pro是一款专业的卸载工具,它不仅具…

低代码PAAS加速推进企业数字化转型

无论是“十四五”规划从国家层面提出的“加快数字化发展 建设数字中国”,还是后疫情时代企业自身的感受,数字化转型已成为必答题。当前 企业 业务场景化、线上趋势愈加明显,越来越多并发的数字化应用场景,而原有集中式架构扩展能力…

2024王道考研计算机组成原理——中央处理器

CPU的运算器其实就是进行固定的数据处理,后面讲的CPU主要侧重的是它的控制器功能 运算器的基本结构 左右两边都是16位,因为寄存器可能位于左右两端的一边(源/目的操作数) A、B两端都要接一堆线 通用寄存器 ALU都在运算器当中 从主存来的数据直接放到…

我在Vscode学OpenCV 处理图像

既然我们是面向Python的OpenCV(OpenCV for Python)那我们就必须要熟悉Numpy这个库,尤其是其中的数组的库,Python是没有数组的,唯有借助他库才有所实现想要的目的。 # 老三样库--事先导入 import numpy as np import c…

暴涨3倍!通过受感染 USB 窃密的事件愈发变多

2023 年上半年,Mandiant 观察到使用受感染 USB 驱动器窃取机密数据的事件至少增加了3倍。此前,Mandiant 披露了在菲律宾的一次攻击行动。本文将会介绍研究人员发现的两外两次基于 USB 驱动器的网络间谍行动。 CSDN大礼包:《黑客&网络安全…

财务数字化转型的切入点是什么?_光点科技

随着科技的不断进步,数字化转型已经成为各个行业追求的目标,财务领域也不例外。那么,财务数字化转型的切入点在哪里呢?如何确保转型的成功进行? 数据整合与管理 财务数据的准确性与及时性是财务管理的基石。数字化转型…

vue+vant图片压缩后上传

vuevant图片压缩后上传 vue文件写入 <template><div class"home"><van-field input-align"left"><template #input><van-uploaderv-model"fileList.file":after-read"afterRead":max-count"5":…

TypeScript之泛型

一、是什么 泛型程序设计&#xff08;generic programming&#xff09;是程序设计语言的一种风格或范式 泛型允许我们在强类型程序设计语言中编写代码时使用一些以后才指定的类型&#xff0c;在实例化时作为参数指明这些类型 在typescript中&#xff0c;定义函数&#xff0c;…

自主创建抖音商城小程序源码系统 带完整搭建教程

随着抖音平台的日益普及&#xff0c;越来越多的商家和用户选择在抖音上开展业务。抖音作为一款短视频社交平台&#xff0c;拥有庞大的用户群体和广阔的市场前景。今天罗峰就来给大家介绍一款抖音商城小程序源码系统&#xff0c;帮助用户快速创建自己的抖音商城&#xff0c;从而…