为什么 Mysql 不建议用 select *

为什么 Mysql 不建议用 select *

学习改变命运,技术铸就辉煌。

大家好,我是銘,全栈开发程序员。

今天在开阿里的开发手册时,看到了说在查询表的时候,一律不得使用 * 作为查询的字段列表,需要使用哪些字段必须明确写明。那今天我们就来说说为啥不能使用 * 。

image-20240203232106133
image-20240203232106133

增加查询分析器解析成本

首先,什么时分析器呢,我给大家画个图说一下,

image-20240203233544053
image-20240203233544053

里面的这个分析器,会去解析你要执行的 sql 语法,词法。

比如,如果是 select * from stu , 看到 * 之后,那么就去看看那个表 stu, 然后数据库先 Query Table Metadata For Columns(查询列的表元数据),把所有列值都给你解析出来,一定程度上为数据库增加了负担。但如果是 select name, id from stu ,那么只需要解析 name 和 id 这两列的值。

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

这个就很好理解了,你查询的字段要和 resultMap 里保持一致,这个就属于规范了,不用多说。

无用字段增加网络消耗、磁盘IO开销

这一点详细说说,看我上面的图,当没有缓存的时候,最终会走到执行器,执行器后面就是引擎层,引擎层里面其实包括了各种日志(undo、redo、binlog 等)的记录, 还有就是在内存里找数据。 简单点归纳,其实这种查询操作就是刷盘操作,从磁盘刷入内存,涉及到的 磁盘IO开销。

那么在刷盘操作的时候,是不是真的selec * 就真的会 增加 磁盘IO开销呢?

答案 :是。 那么会有多大影响呢,那我来分析一下。

如果表里面就四个字段,name、id、address、age。 本来要查询 name , 我直接使用 select * ,多查了三个字段,增大了 IO 开销,但是可以忽略不记。因为没增大多少。

那什么时候要注意呢?

比如表里面有大字段 text 、longtext、blob、tinytext、mediumtext、longblob、mediumblob、tinybob 这些字段在 mysql 里,会被当作一个独立的对象处理。那么这个时候就要谨慎了。读取的内容多,磁盘 IO 开销很大,返回的数据包给客户端量也多,那对查询效率就有很大影响了。

无法使用索引覆盖

使用 select * 无法使用索引覆盖。

什么是索引覆盖?

给 name 字段建索引,查询的时候,只用到了索引的字段,这就是索引覆盖。

比如 select name from stu where id = 1 , 也即是直接通过查询索引,拿出来的数据就已经满足了查询返回的字段数据,无需再额外查询其他字段,这就是索引覆盖。这样的查询效率肯定高。

那如果写成了 select * , 变成查多了其他字段, 那其他字段不是索引,肯定无法触发索引覆盖使用场景了,也就是需要额外的回表查询操作了,那这样就慢了。

总结

  1. 如果表里有大字段,TEXT 、BLOB系列类型字段, 不可使用 select * 。
  2. 如果本来只查询某 1,2 个比较常用的字段的,可以给这些字段建单个索引或者组合索引 ,这时候查询就避免 使用 SELECT *,尽量能触发索引覆盖。
  3. 如果表字段不多,也没啥特殊字段类型,使用 select * 问题也不大。

大学C语言、Java、数据结构、离散数学答案+几十本编程电子书 ,免费分享

链接:https://pan.baidu.com/s/1ES7FZxY-Gi_ZvEUE1-qgLg
提取码:75ol

  • 18
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值