为什么不建议使用SELECT * ?

"避免使用SELECT *"已成为MySQL数据库操作中的一项重要准则,甚至连《阿里Java开发手册》也明确禁止将作为查询字段列表。

在实际开发过程中,可能会有小伙伴贪图方便,直接用*号代替了要返回的字段,特别是后期发现要添加返回的字段时,无需改动sql语句,可是这是一种不好的做法,接下来说说理由。

1.增加磁盘I/O开销

使用select * 会导致增加磁盘I/O的开销,特别是包含那种大字段的时候,可能现在表中就十个字段,可是随着业务的发展,表字段增加到了六十个,可是你这里的需求根本就不需要那几十个字段的,但是就因为你这里写的是select *,导致把那些多余的字段都给查出来了。在mysql中,数据通常都是存储在磁盘上的,因此查询操作是会涉及到磁盘I/O的。查询的字段增多,要读取的内容自然会增多,磁盘I/O的开销自然相应的增大,尤其是那种TEXT、LONGTEXT、MEDIUMTEXT大字段类型,这种影响更加明显。

2.增加网络时延

当数据库查询返回的字段数量增加(尤其是包含大字段如TEXTBLOB等)时,数据包体积会显著增大,导致以下问题:

  1. ‌网络传输次数增加:

    • 大字段可能超出TCP单次传输的最大数据包(MTU)限制,需分片传输,增加往返次数(RTT)‌。

    • 例如,MySQL默认的max_allowed_packet为64MB(mysql版本不同,这个值可能不同,可以通过show variables like 'max_allowed_packet'命令去进行确认),若查询结果超过此值,需多次传输‌。

  2. ‌时延累积:

    • 即使在同一台机器上,TCP协议仍需完成三次握手、数据确认等流程,每次传输均引入微秒级延迟‌。

3.无法利用覆盖索引

select *这种写法是会导致无法利用覆盖索引的。我们举个例子来说明这个问题,假设我们有一张user_info表,表的存储引擎用的是InnoDB,表字段都有id、age、name、address,id为主键,我们添加一个名为idx_age_name的联合索引,涵盖了age和name两个字段。

下面是查询语句:

sql 复制代码
select * from user_info where age = 18;

我们可以用explain命令去查看sql语句的执行计划,id主键索引树的叶子节点会包含完整的用户信息字段。

通过执行计划可以看到,是没有用上覆盖索引的,只是使用上了idx_age_name这个索引,但是这个索引里面没有包含address字段(我们的表里面是有address字段的,这里使用了*,代表查出表中的所有字段),所以还需要进行回表,回到主键索引树中找到address字段。

通过执行计划可以看到,如果我们只需要查出age字段和name字段的话,那就写select age,name 就好了,加上我们建有idx_age_name这个联合索引,这样就可以用上覆盖索引这个特性了。

Using index表示查询的列被索引覆盖,因而无需再回表

注意:覆盖索引其实不是一种独立的索引类型,而是一种查询优化的方式。简单说就是当查询的所有字段都包含在索引中时,就可以直接从索引中获取数据,就不需要去回表查询了。比如上面那个例子,因为查询字段(age、name)都包含在索引中,可以直接通过索引获取数据,无需回表操作。

相关推荐
Vane110 小时前
从零开发一个AI插件,经历了什么?
人工智能·后端
9523610 小时前
SpringBoot统一功能处理
java·spring boot·后端
rleS IONS10 小时前
SpringBoot中自定义Starter
java·spring boot·后端
DevilSeagull11 小时前
MySQL(2) 客户端工具和建库
开发语言·数据库·后端·mysql·服务
远洪12 小时前
claude code 国内安装使用
数据库·mysql
TeDi TIVE12 小时前
springboot和springframework版本依赖关系
java·spring boot·后端
雨辰AI12 小时前
SpringBoot3 + 人大金仓 V9 微服务监控实战|Prometheus+Grafana+SkyWalking 全链路监控
数据库·后端·微服务·grafana·prometheus·skywalking
Nicander12 小时前
理解 mybatis 源码:vibe-coding一个mini-mybatis
后端·mybatis
小呆呆66613 小时前
Codex 穷鬼大救星
前端·人工智能·后端
FelixBitSoul13 小时前
缓存淘汰策略全解:从原理到手写实现(Java / Go / Python)
后端·面试