为什么不能写select *

很多人哪怕是刚学习过MYSQL的小白都知道,在优化sql的时候,第一句话就要回答,不要在select语句里边写 * 。咱们就聊聊 * 号可能带给我们的一些问题。

当然如果是你自己维护的项目,比如自己写了个小程序,你爱怎么写就怎么写,反正你的程序又没什么并发量,对性能的要求又不高。但是话说回来,编码容易形成习惯,一旦养成坏习惯,再改回来就比较难了。所以我们日常编码尽量按照约定俗成的方式去进行编码。无规矩不成方圆,所以我们尽量哪怕是自己写代码也不要写select *

言归正传,首先聊一聊一条sql语句它的执行流程,首先MYSQL的server层接收到一条字符串类型的SQL语句,会进行编译、解析、优化,然后生成一个可以由存储引擎识别的执行计划,具体的工作由存储引擎来完成。如果在select的语句当中写了 * 号,我们在解析的过程当中会将 * 号重新解析为所有列字段的名称,这个过程是需要一定损耗的,虽然它很快。当然写了 * 号之后最严重的问题就是本来不需要查询的字段最后也得被查询出来。在学习阶段,我们见过的表大多以小表为主,所以查询的结果影响也不会太大,但是到了企业里边,你会发现很多的表,它的字段不止几个,十几个,有些大一点的表可能几十个,有些宽表甚至能到上百个字段,想一下,本来只需要查询几个字段,到头来。你却给我加载了几十个,这样就会无端的增加磁盘IO,同时会霸占MYSQL的缓存资源。如果我们的MYSQL安装在远端服务器,那么带宽成本也会无端增加。说的简单一点,本来我只需要查询出1M的数据,并且通过网络进行传输,而你却给我查了10M,而这10M数据需要从磁盘加载到内存,再通过网络进行传输。还有,如果我们对查询的字段建立了联合索引,本来可以实现索引覆盖,但是因为你写了 * ,这个性能就丢失了,必须回表重查。我们都知道,对于一个系统而言,影响它性能的关键就是磁盘IO和网络IO,而你写了一个*,两者皆具备了。

所以在一些特殊场景下,一个 * 号可能带来的额外的损耗可能比你想象中的还要大。(完)

ps: 如果有任何疑问,欢迎评论区给我留言


已有 0 条评论

    感谢参与互动!