为什么SELECT * 查询效率低

看着你满怀期待的脸
不经意间
冲破了我对你的平淡
心头一酸
内心又有点波澜
这是否存在隐患
还是暗示某种惨淡

关于MYSQL语句优化的问题,老生常谈,什么尽量避免使用SELECT * ,尽量避免条件使用or,加上limit限制行数…

就在上周,公司的一个项目,功能是在发布文章时不发布保存草稿后,打开草稿重新发布时,地区的name不显示的BUG,主管让我排查了代码,原来是在写sql语句时没有对地区name的字段进行查询。
这时候我勤劳的优点就展现出来了,把那几个字段加上就好了,虽然脑海里浮现出了一个小星星,没错,就是你想的那个小星星。哎呀,真香!(我们公司项目不是很大,数据量也上不去,性能上还没有遇到瓶颈,所以比较放纵哈)

大家不要学我哈,代码优化的必要性还是非常重要的。

效率低?

首先我们先看一下最新发布的《阿里JAVA开发手册泰山版》中是这样说的

关注文末公众号,回复 ‘’手册‘’ ,可获取阿里JAVA开发手册最新版

在这里插入图片描述

增加查询分析器解析成本

MYSQL在执行查询语句需要经过很多阶段的处理,拿到数据也会进行一些处理,这里不过多了解。
而你给出实际需要查询的字段,mysql内部会针对你所查询的字段进行必要优化处理,而查询所有字段在mysql内部虽然也会优化,但优化方案可能会针对其他不需要的字段进行优化处理,效率定然会有所差异。
在这里插入图片描述

增减字段容易与resultMap配置不一致

这个就比较好理解了,相信用过ORM(对象关系映射)的框架的伙伴们秒懂,使用 * 自然需要实体类和数据库字段一一对应(或者进行一一对应的配置)方能舒服的使用。

无用字段增加网络消耗

不需要的字段会增加数据传输时间和网络开销

用 SELECT * 的话,数据库需要解析更多的对象,字段,权限,属性等相关内容,在SQL语句复杂,硬解析解析较多的情况下,会对数据库造成沉重的负担。

增加网络开销

有时会误带上入log,lconMD5之类的无用且大文本大内容字段,数据传输size会几何增涨。如果DB和应用程序不在同一个服务器,进行数据传输的开销就不用多说了吧

即使 mysql 服务器和客户端是在同一台机器上,使用的协议还是 tcp,通信也是需要额外的时间。

IO操作

对于无用的大字段,如 varchar、blob、text,会增加 io 操作
准确来说,长度超过 728 字节的时候,会先把超出的数据序列化到另外一个地方,因此读取这条记录会增加一次 io 操作。(MySQL InnoDB)

"覆盖索引"失效

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+树查询,速度必然会慢很多。

在这里插入图片描述
由于辅助索引的数据比聚集索引少很多,很多情况下,通过辅助索引进行覆盖索引(通过索引就能获取用户需要的所有列),都不需要读磁盘,直接从内存取,而聚集索引很可能数据在磁盘(外存)中(取决于buffer pool的大小和命中率),这种情况下,一个是内存读,一个是磁盘读,速度差异就很显著了,几乎是数量级的差异。

MYSQL设计了这么好的覆盖索引,我们还是要对的起MYSQL的良苦用心的哈

索引是建的越多越好吗

答案自然是否定的

  1. 数据量小的表不需要建立索引,建立会增加额外的索引开销
  2. 不经常引用的列不要建立索引,因为不常用,即使建立了索引也没有多大意义
  3. 经常频繁更新的列不要建立索引,因为肯定会影响插入或更新的效率
  4. 数据重复且分布平均的字段,因此他建立索引就没有太大的效果(例如性别字段,只有男女,不适合建立索引)
  5. 数据变更需要维护索引,意味着索引越多维护成本越高。
  6. 更多的索引也需要更多的存储空间

部分摘选自博客—>>>_陈哈哈

文章持续更新,可以微信搜索「 绅堂Style 」第一时间阅读,回复【资料】有我准备的面试题笔记。
GitHub https://github.com/dtt11111/Nodes 有总结面试完整考点、资料以及我的系列文章。欢迎Star。
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章