从MySQL小表驱动大表说起

news2024/11/10 7:31:46

        刚刚开始学习MySQL的时候,连表查询直接使用left join或者更粗暴点,两个表直接查询,where过滤条件,组装笛卡尔积,最终出现自己想要的结果。

        当然,现在left join也是会用的,毕竟嘛,方便!

         犹记的当时身为初出茅庐去做的一个面试题,类似这种吧:

a表有100条记录,b表有10000条记录,两张表做关联查询时,是将a表放前面效率高,还是b表放前面效率高?

        当然,当时虽然不太懂为啥,也没头铁的硬刚,直接是大表在前,小表在后回答,嘿嘿。

        不过后来好像绕进了胡同,a*b和b*a有个啥子区别?为啥一定要小表驱动大表?

        关于这个,看了不少的文章,其中讲的最深刻,最明了的应该是百度的百家号里面的一篇文章, 由简入深,很能说服人。

        当然,后来有时候也会忘了,又在原地打转,今天就小记一下。

首先,连表查询肯定是需要至少把一张表的数据加载到内存的,然后关联查询,比如sql:

select  u.* from order o left join user u on o.user_id = u.id where u.id = '9527';

        查询的时候,首先将user表的数据加载到MySQL内存,然后去匹配Order表数据。假设user表的数据匹配量是a,Order表的数据匹配量是b,一般来说,on的条件必须是大表的索引,不然,查询速度贼慢,当然小表最好也是索引。还有就是where中的条件,最好也是和on条件的联合索引或者其他主键之类的,这样查询起来会轻松许多。说多了,继续。

        那么根据查询的过程,时间复杂度是a*b吗?

        当然!不是!

        刚开始加载到内存不是还有个操作吗?没错,就是读取User表的操作,也就是a次操作!

所以:小表驱动大表的操作次数就是 a+a*b

那大表驱动小表的操作次数也就很容易得到为:b+b*a

都说了,b是大表,那么b >a,自然(b+b*a) >(a+a*b)

仅仅看扫描的次数,也能看到,小表驱动大表方案更优!

然后,仅仅是如此?

       当然不!

        先说内存方面,将数据加载的内存,然后进行对比,获取到最终的结果,如果大表驱动小表,需要将大表数据加载到内存,无疑,这必然占据大量的系统内存,要知道内存的每一分空间都是珍贵的,内存占用过大,必然会挤压其他线程可以使用的空间。而且如果表数据过大,内存放不下,还必须建立临时表,然后一部分一部分的取数据进行对比,那不用说,更慢!

        再说,数据IO,将表数据加载到系统内存,肯定要消耗系统IO的。如果是小表驱动大表,也就是需要加载a条数据,然后去匹配过滤数据。反过来,就需要加载b条数据,虽然对比数据的时候都是 a*b次,但是明显加载小表更省IO。

        然后,看下数据锁定,可以减少锁竞争的可能,当使用小表驱动大表时,可以避免大表上的锁竞争,因为这些锁会在更早的阶段被获取并且释放。而如果是直接访问大表,则需要在整个查询过程中保持锁定状态,这可能导致其他事务无法正常执行。

        为防忘记,小记一下~

        如有错误,还望斧正

    no sacrifice,no victory~       

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

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

相关文章

如何实现多存储文件传输,镭速提供多存储文件传输解决方案

目前的文件传输系统中,大多数采用的文件传输系统只支持单个的存储。随着科技的发展,存储的类型越来越多,构建的越来越复杂,业务要求越来越多样化,只支持单个存储的文件传输系统是无法满足现有的需求。 为实现高自由度…

Java基础(十九):集合框架

Java基础系列文章 Java基础(一):语言概述 Java基础(二):原码、反码、补码及进制之间的运算 Java基础(三):数据类型与进制 Java基础(四):逻辑运算符和位运算符 Java基础(五):流程控制语句 Java基础(六)&#xff1…

vue3新的组件

1.Fragment - 在Vue2中: 组件必须有一个根标签 - 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中 - 好处: 减少标签层级, 减小内存占用 没有写根标签,也没有报错,如果是在v2中,我们还需要用一个div来包裹它 …

springboot web项目统一时区方案

背景 springboot项目国际化中,会遇到用户选择的时间和最终存到数据库的时间不一致,可能就是项目开发和部署时的时区没有处理好,导致时间转换出现了问题。 先了解时区都有哪些: 1.GMT:Greenwich Mean Time 格林威治…

移动端适配方法:rem+vw

1.百分比设置:几乎不用 因为各种属性百分比参照物(自身/父元素/...需要去查文档)很难统计固定,所以不用百分比进行适配 2.rem单位动态html的font-size 使用rem,因为rem参考html的fz,只需要在不同的屏幕上设置不同的html的fz即可,其他地方全用rem rem的fz尺寸 媒体查询 编写…

推荐系统召回之userCF

基于用户的协同过滤算法userCF 1.1 相似度计算 通过计算用户之间的相似度。这里的相似度指的是两个用户的兴趣相似度。 假设对于用户u uu和v vv,N ( u ) N(u)N(u)指的是用户u uu喜欢的物品集合,N ( v ) N(v)N(v)指的是用户v vv喜欢的物品集合&#xff0…

体验 Kubernetes Cluster API

体验 Kubernetes Cluster API 什么是 Kubernetes Cluster API安装 Kind增加 ulimit 和 inotify创建 Kind 集群安装 clusterctl CLI 工具初始化管理集群创建一个工作负载集群访问工作负载集群部署一个 CNI 解决方案安装 MetalLB部署 nginx 示例清理(参考)capi-quickstart.yaml 文…

C++的类和对象(2)

类和对象 1.类对象模型1.1. 如何计算类对象的大小1.2. 类的存储模式讨论1.3. 类对象的空间符合结构体对齐规则 2. this指针2.1. this指针的引出2.2. this指针的特性2.3.面试题2.4. C语言和C实现栈的对比 1.类对象模型 1.1. 如何计算类对象的大小 class A { public: void Prin…

类加载与卸载

加载过程 其中验证,准备,解析合称链接 加载通过类的完全限定名,查找此类字节码文件,利用字节码文件创建Class对象. 验证确保Class文件符合当前虚拟机的要求,不会危害到虚拟机自身安全. 准备进行内存分配,为static修饰的类变量分配内存,并设置初始值(0或null).不包含final修饰…

用python脚本从Cadence导出xdc约束文件

用python脚本从Cadence导出xdc约束文件 概述转换方法先导出csv文件修改CSV文件 CSV转XDC检查输出XDC文件csv2xdc源代码下载 概述 在Cadence设计完成带有FPGA芯片的原理图的时候,往往需要将FPGA管脚和网络对应关系导入vivado设计软件中,对于大规模FPGA管…

springboot+vue准妈妈孕期交流平台(源码+文档)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的准妈妈孕期交流平台。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:…

C++引用篇

文章目录 一、引用概念及示例二、引用做函数参数二、引用做函数的返回值四、常引用五、引用和指针的区别 一、引用概念及示例 c语言指针存变量地址,然后通过解引用可以访问或者改变变量,且也可以改变指针变量里面存的地址 修改变量这样还需要对指针变量…

Faster RCNN系列3——RPN的真值详解与损失值计算

Faster RCNN系列: Faster RCNN系列1——Anchor生成过程 Faster RCNN系列2——RPN的真值与预测值概述 Faster RCNN系列3——RPN的真值详解与损失值计算 Faster RCNN系列4——生成Proposal与RoI Faster RCNN系列5——RoI Pooling与全连接层 目录 一、RPN真值详解二、…

手把手教你实现el-table实现跨表格禁用选项,以及禁用选择后,对应的全选按钮也要禁用任何操作

哈喽 大家好啊 今天我要实现不能跨表格选择,如果我选择了其中一个表格的选项后,那么其他的表格选项则被禁用 然后我选择了其中一个表格行,我其他的表格选项则应该被禁用 实现代码: 其中关键属性: selectable仅对 typ…

如何保障企业网络安全

随着信息技术的迅速发展,网络已经渗透到了我们生活的方方面面。企业对网络的依赖程度也越来越高,网络安全问题已经成为了企业面临的一个重要挑战。那么,在这个风险重重的网络世界里,我们如何充分利用现有技术保障企业网络安全呢&a…

智能指针——C++

智能指针相较于普通指针的区别&#xff0c;就是智能指针可以不用主动释放内存空间&#xff0c;系统会自动释放&#xff0c;避免了内存泄漏。 1、unique_ptr&#xff1a;独占指针 需包含的头文件&#xff1a;#include <memory> unique_ptr 三种定义方式 先定义一个类 …

learn_C_deep_5 (温故知新、sigend char a = -128的深度理解、unsigned int类型的写法规范)

目录 温故知新 理解"unsigned int a -10;" 如何理解大小端 大小端的概念 大小端是如何影响数据存储的 sigend char a -128的深度理解 10000000为什么是-128&#xff0c;而不是-0 代码练习 unsigned int类型的写法规范 温故知新 理解"unsigned int a…

python数据结构与算法-动态规划(最长公共子序列)

一、最长公共子序列问题 1、问题概念 一个序列的子序列是在该序列中删去若干元素后得 到的序列。 例如&#xff1a;"ABCD”和“BDF”都是“ABCDEFG”的子序列。 最长公共子序列(LCS) 问题: 给定两个序列X和Y&#xff0c;求X和Y长度最大的公共子字列。 例:X"ABBCBDE”…

【ABAQUS Python二次开发】 debug : ini解析ERROR:没有实例属性‘__getintem__’

我的主页&#xff1a; 技术邻&#xff1a;小铭的ABAQUS学习的技术邻主页博客园 : HF_SO4的主页哔哩哔哩&#xff1a;小铭的ABAQUS学习的个人空间csdn&#xff1a;qgm1702 博客园文章链接&#xff1a; https://www.cnblogs.com/aksoam/p/17287136.html abaqus python 搭配ini…

古埃及:金字塔

文章目录 I 建造金字塔1.1 切割巨石1.2 开凿巨石1.3 摞石1.4 大金字塔的入口呈三角形 see also I 建造金字塔 在生活中&#xff0c;事实是正确的&#xff0c;如果理论解释不了现实&#xff0c;需要更正理论。 1.1 切割巨石 建筑材料巨石的切割&#xff1a;把石英砂粘在了铜锯…