为什么代码规范要求SQL语句不要过多的join?
送分题
面试官:有操作过Linux吗?
我:有的呀
面试官:我想查看内存的使用情况该用什么命令
我:free 或者 top
面试官:那你说一下用free命令都可以看到啥信息
我:那,如下图所示 可以看到内存以及缓存的使用情况
total 总内存
used 已用内存
free 空闲内存
buff/cache 已使用的缓存
avaiable 可用内存
面试官:那你知道怎么清理已使用的缓存吗(buff/cache)
我:em… 不知道
面试官:sync; echo 3 > /proc/sys/vm/drop_caches
就可以清理buff/cache了,你说说我在线上执行这条命令做好不好?
我:(送分题,内心大喜)好处大大的有,清理出缓存我们就有更多可用的内存空间, 就跟pc上面xx卫士的小火箭一样,点一下,就释放出好多的内存
面试官:em…., 回去等通知吧
再谈SQL Join
面试官:换个话题,谈谈你对join的理解
我:好的(再答错就彻底完了,把握住机会)
回顾
SQL中的join可以根据某些条件把指定的表给结合起来并将数据返回给客户端
join的方式有
inner join 内连接
left join 左连接
right join 右连接
full join 全连接
图片来源:https://www.cnblogs.com/reaptomorrow-flydream/p/8145610.html
面试官:在项目开发中如果需要使用join语句,如何优化提升性能?
我:分为两种情况,数据规模小的,数据规模大的。
面试官: 然后?
我:对于
1.数据规模较小 全部干进内存就完事了嗷
2.数据规模较大
可以通过增加索引来优化join语句的执行速度
可以通过冗余信息来减少join的次数
尽量减少表连接的次数,一个SQL语句表连接的次数不要超过5次
面试官:可以总结为join语句是相对比较耗费性能,对吗?
我:是的
面试官: 为什么?
缓冲区
我: 在执行join语句的时候必然要有一个比较的过程
面试官: 是的
我:逐条比较两个表的语句是比较慢的,因此我们可以把两个表中数据依次读进一个内存块中, 以MySQL的InnoDB引擎为例,使用以下语句我们必然可以查到相关的内存区域show variables like '%buffer%'
如图所示join_buffer_size的大小将会影响我们join语句的执行性能
面试官: 除此之外呢?
一个大前提
我:任何项目终究要上线,不可避免的要产生数据,数据的规模又不可能太小
面试官: 是这样的
我:大部分数据库中的数据最终要保存到硬盘上,并且以文件的形式进行存储。
以MySQL的InnoDB引擎为例
InnoDB以页(page)为基本的IO单位,每个页的大小为16KB
InnoDB会为每个表创建用于存储数据的.ibd文件
验证
我:这意味着我们有多少表要连接就需要读多少个文件,虽然可以利用索引,但还是免不了频繁的移动硬盘的磁头
面试官:也就是说频繁的移动磁头会影响性能对吧
我:是的,现在的开源框架不都喜欢说自己通过顺序读写大大的提升了性能吗,比如hbase、kafka
面试官:说的没错,那你认为Linux有对此做出优化吗?提示,你可以再执行一次free命令看一下
我:奇怪缓存怎么占用了1.2G多
图片来源:https://www.linuxatemyram.com/
面试官:你有没有想过
buff/cache 里面存的是什么?
为什么buff/cache 占了那么多内存,可用内存即availlable还有1.1G?
为什么你可以通过两条命令来清理buff/cache占用的内存,而想要释放used只能通过结束进程来实现?
品,你细品
思考了几分钟后
我:这么随便就释放了buff/cache所占用的内存,说明它就不重要, 清除它不会对系统的运行造成影响
面试官: 不完全对
我:难道是?想起来《CSAPP》(深入理解计算机系统)里面说过一句话
存储器层次结构的本质是,每一层存储设备都是较低一层设备的缓存
通俗来说,就是说Linux会把内存当作是硬盘的高速缓存
相关资料:http://tldp.org/LDP/sag/html/buffer-cache.html
面试官:现在知道那道送分题应该怎么回答了吧
我:我….
Join算法
面试官:再给你个机会,如果让你来实现Join算法你会怎么做?
我:无索引的话,嵌套循环就完事了嗷。有索引的话,则可以利用索引来提升性能.
面试官:说回join_buffer 你认为join_buffer里面存储的是什么?
我:在扫描过程中,数据库会选择一个表把他要返回以及需要进行和其他表进行比较的数据放进join_buffer
面试官:有索引的情况下是怎么处理的?
我:这个就比较简单了,直接读取两个表的索引树进行比较就完事了嗷,我这边介绍一下无索引的处理方式
Nested Loop Join
嵌套循环,每次只读取表中的一行数据,也就是说如果outerTable有10万行数据, innerTable有100行数据,需要读取10000000次(假设这两个表的文件没有被操作系统给缓存到内存, 我们称之为冷数据表)
当然现在没啥数据库引擎使用这种算法(太慢了)
Block nested loop
Block 块,也就是说每次都会取一块数据到内存以减少I/O的开销
当没有索引可以使用的时候,MySQL InnoDB 就会使用这种算法
考虑以下两个表 t_a 和t_b
当无法使用索引执行join操作的时候,InnoDB会自动使用Block nested loop 算法
总结
上学时,数据库老师最喜欢考数据库范式,直到上班才学会一切以性能为准,能冗余就冗余,实在冗余不了的就join如果join真的影响到性能。试着调大你的join_buffer_size, 或者换固态硬盘。
参考资料
《深入理解计算机系统》- 第6章 存储器层次结构
《Experiments and fun with the Linux disk cache》作者通过几个例子来说明硬盘缓存对程序执行性能的影响
《Linux ate my ram》 Free参数的解释
How to clear the buffer/pagecache (disk cache) under Linux 文章开头送分题命令的解释
MySQL 是怎样运行的:从根儿上理解 MySQL
Block bested loop 来自MariaDB官方文档解释了Block-Nested-Loop算法的实现
以上是为什么代码规范要求SQL语句不要过多的join?的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

HQL和SQL在Hibernate框架中进行比较:HQL(1.面向对象语法,2.数据库无关的查询,3.类型安全),而SQL直接操作数据库(1.与数据库无关的标准,2.可执行复杂查询和数据操作)。

《OracleSQL中除法运算的用法》在OracleSQL中,除法运算是常见的数学运算之一。在数据查询和处理过程中,除法运算可以帮助我们计算字段之间的比例或者得出特定数值的逻辑关系。本文将介绍OracleSQL中除法运算的用法,并提供具体的代码示例。一、OracleSQL中除法运算的两种方式在OracleSQL中,除法运算可以使用两种不同的方式进行

Oracle和DB2是两个常用的关系型数据库管理系统,它们都有自己独特的SQL语法和特点。本文将针对Oracle和DB2的SQL语法进行比较与区别,并提供具体的代码示例。数据库连接在Oracle中,使用以下语句连接数据库:CONNECTusername/password@database而在DB2中,连接数据库的语句如下:CONNECTTOdataba

MyBatis动态SQL标签解读:Set标签用法详解MyBatis是一个优秀的持久层框架,它提供了丰富的动态SQL标签,可以灵活地构建数据库操作语句。其中,Set标签是用于生成UPDATE语句中SET子句的标签,在更新操作中非常常用。本文将详细解读MyBatis中Set标签的用法,以及通过具体的代码示例来演示其功能。什么是Set标签Set标签用于MyBati

SQL中的Identity是什么,需要具体代码示例在SQL中,Identity是一种用于生成自增数字的特殊数据类型,它常用于唯一标识表中的每一行数据。Identity列通常与主键列配合使用,可以确保每条记录都有一个独一无二的标识符。本文将详细介绍Identity的使用方式以及一些实际的代码示例。Identity的基本使用方式在创建表时,可以使用Identit

在Springboot+Mybatis-plus不使用SQL语句进行多表添加操作我所遇到的问题准备工作在测试环境下模拟思维分解一下:创建出一个带有参数的BrandDTO对象模拟对后台传递参数我所遇到的问题我们都知道,在我们使用Mybatis-plus中进行多表操作是极其困难的,如果你不使用Mybatis-plus-join这一类的工具,你只能去配置对应的Mapper.xml文件,配置又臭又长的ResultMap,然后再去写对应的sql语句,这种方法虽然看上去很麻烦,但具有很高的灵活性,可以让我们

解决办法:1、检查登录用户是否具有足够的权限来访问或操作该数据库,确保该用户具有正确的权限;2、检查SQL Server服务的帐户是否具有访问指定文件或文件夹的权限,确保该帐户具有足够的权限来读取和写入该文件或文件夹;3、检查指定的数据库文件是否已被其他进程打开或锁定,尝试关闭或释放该文件,并重新运行查询;4、尝试以管理员身份运行Management Studio等等。

如何使用SQL语句在MySQL中进行数据聚合和统计?在进行数据分析和统计时,数据聚合和统计是非常重要的步骤。MySQL作为一个功能强大的关系型数据库管理系统,提供了丰富的聚合和统计函数,可以很方便地进行数据聚合和统计操作。本文将介绍使用SQL语句在MySQL中进行数据聚合和统计的方法,并提供具体的代码示例。一、使用COUNT函数进行计数COUNT函数是最常用
