面试官:到底是什么原因才导致 select * 效率低下的? 迈不过友情╰ 2022-10-29 06:23 127阅读 0赞 ## 你知道的越多,不知道的就越多,业余的像一棵小草! ## 你来,我们一起精进!你不来,我和你的竞争对手一起精进! ## 编辑:业余草 ## ## blog.csdn.net/qq\_39390545/article/details/106766965 ## ## 推荐:https://www.xttblog.com/?p=5151 ## > 面试官:“小陈,说一下你常用的SQL优化方式吧。” > 陈小哈:“那很多啊,比如不要用SELECT \*,查询效率低。巴拉巴拉...” > > 面试官:“为什么不要用SELECT \* ?它在哪些情况下效率低呢?” > 陈小哈:“SELECT \* 它好像比写指定列名多一次全表查询吧,还多查了一些无用的字段。” > > 面试官:“嗯...” > 陈小哈:“emmm~ 没了” > > 陈小哈:“....??(几个意思)” > > 面试官:“嗯...好,那你还有什么要问我的么?” > 陈小哈:“我问你个锤子,把老子简历还我!” ![format_png][] > **技术的突飞猛进往往是自然发生的。你在某个夜晚苦熬一个知识点时, 不会觉得自己突飞猛进;只有在多年后的某日, 熟练地给别人讲解这个知识点后, 内心才会小小地波动一下, 猛然忆起当年深夜中的青灯一盏。** 无论在工作还是面试中,关于SQL中不要用“SELECT \*”,都是大家听烂了的问题,虽说听烂了,但普遍理解还是在很浅的层面,并没有多少人去追根究底,探究其原理。 废话不多说,本文带你深入了解一下"SELECT \* "效率低的原因及场景。 > 本文很干!请自备茶水,没时间看记得先收藏 -- 来自一位被技术经理毒打多年的程序员的忠告 ## 目录 ## 一、效率低的原因 1. 不需要的列会增加数据传输时间和网络开销 2. 对于无用的大字段,如 varchar、blob、text,会增加 io 操作 3. 失去MySQL优化器“覆盖索引”策略优化的可能性 二、索引知识延申 ● 联合索引 (a,b,c) ● 联合索引的优势 1) 减少开销 2)覆盖索引 3)效率高 ● 索引是建的越多越好吗 三、心得体会 -------------------- ## 一、效率低的原因 ## > 4 - 1. 【强制】在表查询中,一律不要使用 \* 作为查询的字段列表,需要哪些字段必须明确写明。 说明: * 增加查询分析器解析成本。 * 增减字段容易与 resultMap 配置不一致。 * 无用字段增加网络 消耗,尤其是 text 类型的字段。 开发手册中比较概括的提到了几点原因,让我们深入一些看看: ### 1. 不需要的列会增加数据传输时间和网络开销 ### 1. 用“SELECT \* ”数据库需要解析更多的对象、字段、权限、属性等相关内容,在 SQL 语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担。 2. 增大网络开销;\* 有时会误带上如log、IconMD5之类的无用且大文本字段,数据传输size会几何增涨。如果DB和应用程序不在同一台机器,这种开销非常明显 3. 即使 mysql 服务器和客户端是在同一台机器上,使用的协议还是 tcp,通信也是需要额外的时间。 ### 2. 对于无用的大字段,如 varchar、blob、text,会增加 io 操作 ### 准确来说,长度超过 728 字节的时候,会先把超出的数据序列化到另外一个地方,因此读取这条记录会增加一次 io 操作。(MySQL InnoDB) ### 3. 失去MySQL优化器“覆盖索引”策略优化的可能性 ### SELECT \* 杜绝了覆盖索引的可能性,而基于MySQL优化器的“覆盖索引”策略又是速度极快,效率极高,业界极为推荐的查询优化方式。 例如,有一个表为t(a,b,c,d,e,f),其中,a为主键,b列有索引。 那么,在磁盘上有两棵 B+ 树,即聚集索引和辅助索引(包括单列索引、联合索引),分别保存(a,b,c,d,e,f)和(a,b),如果查询条件中where条件可以通过b列的索引过滤掉一部分记录,查询就会先走辅助索引,如果用户只需要a列和b列的数据,直接通过辅助索引就可以知道用户查询的数据。 如果用户使用`select *`,获取了不需要的数据,则首先通过辅助索引过滤数据,然后再通过聚集索引获取所有的列,这就多了一次b+树查询,速度必然会慢很多。 ![format_png 1][] 我去,为什么最左前缀原则失效了? 由于辅助索引的数据比聚集索引少很多,很多情况下,通过辅助索引进行覆盖索引(通过索引就能获取用户需要的所有列),都不需要读磁盘,直接从内存取,而聚集索引很可能数据在磁盘(外存)中(取决于buffer pool的大小和命中率),这种情况下,一个是内存读,一个是磁盘读,速度差异就很显著了,几乎是数量级的差异。 ![format_png 2][] ## 二、索引知识延申 ## 上面提到了辅助索引,在MySQL中辅助索引包括单列索引、联合索引(多列联合),单列索引就不再赘述了,这里提一下联合索引的作用 ### 联合索引 (a,b,c) ### 联合索引 (a,b,c) 实际建立了 (a)、(a,b)、(a,b,c) 三个索引 我们可以将组合索引想成书的一级目录、二级目录、三级目录,如index(a,b,c),相当于a是一级目录,b是一级目录下的二级目录,c是二级目录下的三级目录。要使用某一目录,必须先使用其上级目录,一级目录除外。 如下: ![format_png 3][] ### 联合索引的优势 ### #### 1) 减少开销 #### 建一个联合索引 (a,b,c) ,实际相当于建了 (a)、(a,b)、(a,b,c) 三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销! #### 2)覆盖索引 #### 对联合索引 (a,b,c),如果有如下 sql 的, SELECT a,b,c from table where a='xx' and b = 'xx'; 那么 MySQL 可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机 io 操作。减少 io 操作,特别是随机 io 其实是 DBA 主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。 #### 3)效率高 #### 索引列多,通过联合索引筛选出的数据越少。比如有 1000W 条数据的表,有如下SQL: select col1,col2,col3 from table where col1=1 and col2=2 and col3=3; 假设:假设每个条件可以筛选出 10% 的数据。 * A. 如果只有单列索引,那么通过该索引能筛选出 1000W10%=100w 条数据,然后再回表从 100w 条数据中找到符合 col2=2 and col3= 3 的数据,然后再排序,再分页,以此类推(递归); * B. 如果是(col1,col2,col3)联合索引,通过三列索引筛选出 1000w10% 10% \*10%=1w,效率提升可想而知! ### 索引是建的越多越好吗 ### 答案自然是否定的 * 数据量小的表不需要建立索引,建立会增加额外的索引开销 * 不经常引用的列不要建立索引,因为不常用,即使建立了索引也没有多大意义 * 经常频繁更新的列不要建立索引,因为肯定会影响插入或更新的效率 * 数据重复且分布平均的字段,因此他建立索引就没有太大的效果(例如性别字段,只有男女,不适合建立索引) * 数据变更需要维护索引,意味着索引越多维护成本越高。 * 更多的索引也需要更多的存储空间 ## 三、心得体会 ## 相信能看到这里这老铁要么是对MySQL有着一腔热血的,要么就是喜欢滚鼠标的。来了就是缘分,如果从本文学到了东西,请不要吝啬手中的赞哦,拒绝白嫖~ 有朋友问我,你对SQL规范那么上心,平时你写代码不会用SELECT \* 吧? 咋可能啊,天天用。。代码里也在用(一脸羞愧),其实我们的项目普遍很小,数据量也上不去,性能上还没有遇到瓶颈,所以比较放纵。 写本篇文章主要是这个知识点网上总结的很少很散,也不规范,算是给自己也是给大家总结一份比较详细的,值得记一下的。以后给面试官说完让他没法找你茬。 顺便吹波牛B,谢谢各位。 ![format_png 4][] [format_png]: /images/20221024/5c4661bbfb7a43dfad2473acd0551089.png [format_png 1]: /images/20221024/a92e94792769480a85b8f4ac5be2f02a.png [format_png 2]: /images/20221024/c73ca6cd2ae74defbd6814777da9aff6.png [format_png 3]: /images/20221024/d300fbea2e8b4cbdaebefd95b9e4c4f0.png [format_png 4]: /images/20221024/f902854679b9490c92db2d4755dea34f.png
相关 Java字符串连接操作效率低下的原因分析 Java字符串连接操作效率低下主要源于以下几个原因: 1. **频繁创建对象**:每次使用+或concat方法连接字符串时,都会生成一个新的String对象。对于大量字符串的 偏执的太偏执、/ 2024年09月15日 15:57/ 0 赞/ 12 阅读
相关 Java Swing界面渲染效率低下的原因及解决方案 Java Swing是Java GUI工具包,它提供了许多组件如按钮、文本框等,用于构建用户界面。然而,Swing在界面渲染效率方面可能存在以下问题: 1. **重绘机制** 水深无声/ 2024年09月10日 03:54/ 0 赞/ 12 阅读
相关 Zookeeper脑裂是什么原因导致的? Zookeeper 脑裂问题通常是由于网络分区、节点故障或配置错误等原因导致的。以下是一些可能导致 Zookeeper 脑裂的原因: 1. 网络分区:Zookeeper 使 淩亂°似流年/ 2024年02月05日 16:07/ 0 赞/ 2 阅读
相关 面试官:进程与线程的关系和区别到底是什么? 相信大家面试时一定没少被一个问题刁难,那就是进程和线程的区别是什么?这个问题延申开来并不像表面那么简单,今天就来深入一探。 开始前先看一组非常传神的图例,相信可以帮助你更好理 £神魔★判官ぃ/ 2023年09月25日 23:34/ 0 赞/ 81 阅读
相关 什么原因导致芯片短路_是什么原因导致手机网速慢! 会导致手机上网速度慢的原因有运营商原因、手机本身的性能变差、基站拥堵、天气恶劣,详细介绍如下: 1. 手机本身的内存较小,存放的文件较多,芯片性能较差,运行的程序较多,使得 川长思鸟来/ 2023年01月03日 14:09/ 0 赞/ 120 阅读
相关 面试官:到底是什么原因才导致 select * 效率低下的? 你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 blog.csdn.net/qq\ 迈不过友情╰/ 2022年10月29日 06:23/ 0 赞/ 128 阅读
相关 面试时,面试官到底在考察什么? 作者:白海飞 出处:极客时间《面试现场》专栏 先看一段面试对话,“大面”是一位久经沙场的面试官,小明就是今天的应聘者。一通面试下来,前面的技术问题小明都对答如流,双方相谈 朴灿烈づ我的快乐病毒、/ 2022年02月22日 05:26/ 0 赞/ 285 阅读
相关 效率低下?是管理者无能?还是“太宽容”? 效率低下?是管理者无能?还是“太宽容”? 效率低下,是当前许多企业都会面临的难题之一。 一些企业甚至还会出现这样一种“神奇”的现象:老板和员工都在努力工作,公司上下几乎每 Myth丶恋晨/ 2022年01月15日 06:17/ 0 赞/ 232 阅读
相关 面试官们“爱不释手”的分布式系统架构到底是个什么鬼? 点击上方石杉的架构笔记,右上选择“设为星标” 每日早8点半,精品技术文章准时送上 ![640?wx\_fmt=png][640_wx_fmt_png] 我不是女神ヾ/ 2022年01月14日 16:51/ 0 赞/ 180 阅读
还没有评论,来说两句吧...