当前位置: 首页 > 后端技术 > Java

面试官问:为什么不推荐使用Select-?请大声回答他!!

时间:2023-04-02 00:40:04 Java

作者:小目标青年\来源:https://blog.csdn.net/qq_3538...序言中不建议使用select*字眼,开发不陌生。上面也提到了阿里的开发手册:这个完整版可以通过关注公众号Java核心技术,然后在公众号后台回复手册获得。昨晚收到一个小哥的反馈:然后我也问了学习组的兄弟们,不敢说什么:好像发:离谱:那我作为射手,必须射。射手:成语,xxxxx来了,我就开枪。完整版正文可通过关注公众号Java核心技术,然后在公众号后台回复说明书获取。其实阿里巴巴手册上解释了三点:1)增加查询分析器的分析成本。什么是分析仪成本?它是什么?SQL语法,词法。比如是select*fromuser,看到*就去看看user是哪个表,然后QueryTableMetadataForColumns会给你所有的列值,填上selectid之类的,姓名,年龄,电话表格用户这样。(当然还有其他的分析,比如语法判断,字段判断,表名等等)说实话。这个分析器的成本……如果说增加了解析的成本,我还真能理解。但是感觉开销不是很大。。。除非是大表,大到把所有列值都查询出来?所以,我可以接受,但不多。2)不想说增减字段容易和resultMap配置不一致。老实说,有时我写select*(当我需要查找表中所有的列值时),我在实体中添加字段,我更改resultMap,我还不需要移动sql.这一点属于平时使用规范中的规避点,就不多说了。3)无用字段增加网络消耗和磁盘IO开销。你可以看到我在第一点画的草图。如果不考虑缓存的存在:最终还是会走到executor,然后engine层其实是在executor的后面。这里不展开引擎层。引擎层其实就是包括各种日志(undo、redo、binlog等)的记录,在内存中查找数据。简单来说,这种查询操作其实就是磁盘刷新操作,涉及到磁盘IO开销。那么在刷机操作过程中,selec*是不是真的会增加磁盘IO开销呢?答案是肯定的。但是增加的影响力,不得不说一句:如果说,表中只有三个字段,id,name,age,本来查id,name;因为select*,变成了额外的agecheck,增加了diskIOOverhead?我认为它增加了,但这几乎是不合理的。由于这些是普通数据类型,因此开销不会增加太多。那么,什么才是真正的地雷呢?有tinytext、text、mediumtext、longtexttinybob、blob、mediumblob、longblob等大字段,在mysql上,它们被视为一个独立的对象。这时候你真的要小心了。如果你有一个字段很多的表,比如意见反馈表,消息长度不确定,用的是文本,回复消息字段也是用文本;另一个例子是博客文本表,为了存储内容,使用了这些大字段。本来想查反馈的人的名字,或者博客的标题,但是因为懒或者没注意,就写了select*.,查询的时候把这些大字段都带出来了。那么很明显,此时读取的内容数据真的比初衷大很多(可能楼主小丹投诉了保安,反馈信息给你写了小纸条),此时因为内容量大读取,磁盘IO开销很大,然后返回给客户端的数据包也很多,所以确实有影响。4)补充,其实也是我要说的第一点,不能用索引覆盖ps:今天学成语了吗?不要乱用成语。select*基本告别指数覆盖什么是指数覆盖?示例:为name字段建立索引,查询时只使用被索引的字段,这就是索引覆盖。即直接查询索引,得到的数据已经满足查询返回的字段数据。不需要额外的查询操作,即索引覆盖。这肯定很快。如果本意是查名字,结果写成select*,变成了更多的其他字段去查,那其他字段就不是索引,肯定不可能触发索引覆盖使用场景,也就是需要额外的查询操作回表,所以会变慢。回到正题,因为写成select*,就变成其他字段太多了,查不到,其他字段又不是索引,导致回表慢。哪里有问题?是因为其他字段不是索引吗?然后为其他字段建立索引,就完了,兄弟们。千万不能这么乱来,索引的维护成本是不容忽视的。涉及修改、增删数据时索引的维护成本,索引页的拆分与合并等。索引也需要保存,也需要占用磁盘空间。而如果N个字段都是索引,如果随意更改一行数据,就需要维护N个索引。什么概念,就像我们平时写一个word文档,创建一个目录,然后二级标题,三级标题,文字,分页,编辑这些乱七八糟的操作都需要刷新目录.那么这个指数覆盖的影响真的很大吗?取出200W数据的表,删除所有索引,单独给platform_sn加一个索引:然后先尝试索引覆盖的查询,看时间,0.02秒:然后改成select*:当然是这个200W数据的场景,但是可以看出时间差距还是很明显的。0.02到0.179....如果我们再添加几个大字段呢?文……那估计真是离谱。目标总结:如果表中有大字段,比如TEXT、BLOB系列字段,使用SELECT*。注意,如果只查询一个或两个常用字段,可以为这些字段建立单一索引或组合索引。此时避免使用SELECT*进行查询。最好尽可能多地触发索引覆盖。如果表字段不多,也没有特殊的字段类型,必须有多个列去查,不能触发索引覆盖,我觉得应该用SELECT。*没关系,或者写一个列出所有的字段,这样复制代码也方便(因为会出现这个字段在数据库中存在,但是查不到的情况,这种情况select*不如写select方便,只需要去掉中的某个字段即可)。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!