赞
踩
学习改变命运,技术铸就辉煌。
大家好,我是銘,全栈开发程序员。
今天在开阿里的开发手册时,看到了说在查询表的时候,一律不得使用 * 作为查询的字段列表,需要使用哪些字段必须明确写明。那今天我们就来说说为啥不能使用 * 。
首先,什么时分析器呢,我给大家画个图说一下,
里面的这个分析器,会去解析你要执行的 sql 语法,词法。
比如,如果是 select * from stu , 看到 * 之后,那么就去看看那个表 stu, 然后数据库先 Query Table Metadata For Columns(查询列的表元数据),把所有列值都给你解析出来,一定程度上为数据库增加了负担。但如果是 select name, id from stu ,那么只需要解析 name 和 id 这两列的值。
这个就很好理解了,你查询的字段要和 resultMap 里保持一致,这个就属于规范了,不用多说。
这一点详细说说,看我上面的图,当没有缓存的时候,最终会走到执行器,执行器后面就是引擎层,引擎层里面其实包括了各种日志(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 * , 变成查多了其他字段, 那其他字段不是索引,肯定无法触发索引覆盖使用场景了,也就是需要额外的回表查询操作了,那这样就慢了。
大学C语言、Java、数据结构、离散数学答案+几十本编程电子书 ,免费分享
链接:https://pan.baidu.com/s/1ES7FZxY-Gi_ZvEUE1-qgLg
提取码:75ol
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。