“面试官:“小陈,说一下你常用的SQL优化方式吧。” 陈小哈:“那很多啊,比如不要用SELECT *,查询效率低。巴拉巴拉…”面试官:“为什么不要用SELECT * ?它在哪些情况下效率低呢?” 陈小哈:“SELECT * 它好像比写指定列名多一次全表查询吧,还多查了一些无用的字段。”面试官:“嗯…” 陈小哈:“emmm~ 没了”陈小哈:“…??(几个意思)”面试官:“嗯…好,那你还有什么要问我的么?” 陈小哈:“我问你个锤子,把老子简历还我!”

无论在工作还是面试中,关于SQL中不要用“SELECT *”,都是大家听烂了的问题,虽说听烂了,但普遍理解还是在很浅的层面,并没有多少人去追根究底,探究其原理。

废话不多说,本文带你深入了解一下"SELECT * "效率低的原因及场景。

一、效率低的原因

先看一下最新《阿里java开发手册(泰山版)》中 MySQL 部分描述:

4 - 1. **【强制】**在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。说明:

  • 增加查询分析器解析成本。
  • 增减字段容易与 resultMap 配置不一致。
  • 无用字段增加网络 消耗,尤其是 text 类型的字段。

开发手册中比较概括的提到了几点原因,让我们深入一些看看:

1.不需要的列会增加数据传输时间和网络开销

1、用“SELECT * ”数据库需要解析更多的对象、字段、权限、属性等相关内容,在 SQL 语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担。

2、增大网络开销;* 有时会误带上如log、IconMD5之类的无用且大文本字段,数据传输size会几何增涨。如果DB和应用程序不在同一台机器,这种开销非常明显

3、即使 mysql 服务器和客户端是在同一台机器上,使用的协议还是 tcp,通信也是需要额外的时间。

2.对于无用的大字段,如 varchar、blob、text,会增加 io 操作

准确来说,长度超过 728 字节的时候,会先把超出的数据序列化到另外一个地方,因此读取这条记录会增加一次 io 操作。(MySQL InnoDB)

3.失去MySQL优化器“覆盖索引”策略优化的可能性

SELECT * 杜绝了覆盖索引的可能性,而基于MySQL优化器的“覆盖索引”策略又是速度极快,效率极高,业界极为推荐的查询优化方式。

例如,有一个表为t(a,b,c,d,e,f),其中,a为主键,b列有索引。

那么,在磁盘上有两棵 B+ 树,即聚集索引和辅助索引(包括单列索引、联合索引),分别保存(a,b,c,d,e,f)和(a,b),如果查询条件中where条件可以通过b列的索引过滤掉一部分记录,查询就会先走辅助索引,如果用户只需要a列和b列的数据,直接通过辅助索引就可以知道用户查询的数据。

如果用户使用select *,获取了不需要的数据,则首先通过辅助索引过滤数据,然后再通过聚集索引获取所有的列,这就多了一次b+树查询,速度必然会慢很多。

由于辅助索引的数据比聚集索引少很多,很多情况下,通过辅助索引进行覆盖索引(通过索引就能获取用户需要的所有列),都不需要读磁盘,直接从内存取,而聚集索引很可能数据在磁盘(外存)中(取决于buffer pool的大小和命中率),这种情况下,一个是内存读,一个是磁盘读,速度差异就很显著了,几乎是数量级的差异。

二、索引知识延申

上面提到了辅助索引,在MySQL中辅助索引包括单列索引、联合索引(多列联合),单列索引就不再赘述了,这里提一下联合索引的作用

联合索引 (a,b,c)

联合索引 (a,b,c) 实际建立了 (a)、(a,b)、(a,b,c) 三个索引

我们可以将组合索引想成书的一级目录、二级目录、三级目录,如index(a,b,c),相当于a是一级目录,b是一级目录下的二级目录,c是二级目录下的三级目录。要使用某一目录,必须先使用其上级目录,一级目录除外。

如下:

联合索引的优势

1) 减少开销
建一个联合索引 (a,b,c) ,实际相当于建了 (a)、(a,b)、(a,b,c) 三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!

2)覆盖索引
对联合索引 (a,b,c),如果有如下 sql 的,

SELECT a,b,c from table where a='xx' and b = 'xx';

那么 MySQL 可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机 io 操作。减少 io 操作,特别是随机 io 其实是 DBA 主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。

3)效率高

索引列多,通过联合索引筛选出的数据越少。比如有 1000W 条数据的表,有如下SQL:

select col1,col2,col3 from table where col1=1 and col2=2 and col3=3;

假设:假设每个条件可以筛选出 10% 的数据。

  • A. 如果只有单列索引,那么通过该索引能筛选出 1000W10%=100w 条数据,然后再回表从 100w 条数据中找到符合 col2=2 and col3= 3 的数据,然后再排序,再分页,以此类推(递归);
  • B. 如果是(col1,col2,col3)联合索引,通过三列索引筛选出 1000w10% 10% *10%=1w,效率提升可想而知!

索引是建的越多越好吗

答案自然是否定的

  • 数据量小的表不需要建立索引,建立会增加额外的索引开销
  • 不经常引用的列不要建立索引,因为不常用,即使建立了索引也没有多大意义
  • 经常频繁更新的列不要建立索引,因为肯定会影响插入或更新的效率
  • 数据重复且分布平均的字段,因此他建立索引就没有太大的效果(例如性别字段,只有男女,不适合建立索引)
  • 数据变更需要维护索引,意味着索引越多维护成本越高。
  • 更多的索引也需要更多的存储空间

三、心得体会
相信能看到这里这老铁要么是对MySQL有着一腔热血的,要么就是喜欢滚鼠标的。来了就是缘分,如果从本文学到了东西,请不要吝啬手中的赞哦,拒绝白嫖~

有朋友问我,你对SQL规范那么上心,平时你写代码不会用SELECT * 吧?

咋可能啊,天天用。。代码里也在用(一脸羞愧),其实我们的项目普遍很小,数据量也上不去,性能上还没有遇到瓶颈,所以比较放纵。

写本篇文章主要是这个知识点网上总结的很少很散,也不规范,算是给自己也是给大家总结一份比较详细的,值得记一下的。以后给面试官说完让他没法找你茬

顺便吹波牛B,谢谢各位。

来源:blog.csdn.net/qq_39390545/article/details/106766965

为什么大家都说 SELECT * 效率低相关推荐

  1. 为什么大家都说 SELECT * 效率低?

    版权声明:本文为CSDN博主「_陈哈哈」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/qq_39390545/ ...

  2. nbear分页 效率低_为什么大家都说“SELECT *”效率低?

    " 无论在工作还是面试中,关于 SQL 中不要用"SELECT *",都是大家听烂了的问题,虽说听烂了,但普遍理解还是在很浅的层面,并没有多少人去追根究底,探究其原理. ...

  3. 面试了3家公司,都问我:为什么大家都说 SELECT * 效率低?

    相关阅读:一个90后员工猝死的全过程 来源:blog.csdn.net/qq_39390545/article/details/106766965 面试官:"小陈,说一下你常用的SQL优化方 ...

  4. 为什么大家都说SELECT * 效率低 ?

    面试官:"小陈,说一下你常用的SQL优化方式吧." 陈小哈:"那很多啊,比如不要用SELECT *,查询效率低.巴拉巴拉..." 面试官:"为什么不要 ...

  5. MySql | 为什么大家都在说 Select * 效率低

    Hi ! 我是小小,今天带来本周的第三篇.为什么大家都在说 Select * 效率低. 面试现场 面试官:"小小啊,说一说你常用的SQL优化方式吧". 小小:"很多的,相 ...

  6. 同一目录下有大量文件会影响效率吗_到底是什么原因才导致 select * 效率低下的?

    面试官:"小陈,说一下你常用的SQL优化方式吧." 陈小哈:"那很多啊,比如不要用SELECT *,查询效率低.巴拉巴拉..." 面试官:"为什么不要 ...

  7. mysql越筛越少_面试官:为什么SELECT * 会导致查询效率低?

    面试官:"小陈,说一下你常用的SQL优化方式吧." 陈小哈:"那很多啊,比如不要用SELECT *,查询效率低.巴拉巴拉..." 面试官:"为什么不要 ...

  8. 到底是什么原因才导致 select * 效率低下的?

    面试官:"小陈,说一下你常用的SQL优化方式吧." 陈小哈:"那很多啊,比如不要用SELECT *,查询效率低.巴拉巴拉..." 面试官:"为什么不要 ...

  9. 大家都说 Java 反射效率低,为什么呢?

    我们在 Java 开发中,难免会接触到反射,而在一些框架中,反射的运用更是常见.我相信,每次提到反射,大家的第一反应一定是反射效率低,尽量少使用.但是反射的效率到底低多少?反射效率低的原因在哪里?这篇 ...

  10. @老板:别开视频会议了,效率低没人care,斯坦福、微软都可以作证

    贾浩楠 发自 凹非寺 量子位 报道 | 公众号 QbitAI 必须吐槽一下视频会议这件事. 复工绊脚石,尴尬制造机. 时间长效率低,一不小心还容易成为"快乐源泉": 微软的一群员工 ...

最新文章

  1. AI科研绘图3:排版
  2. poj_2739 尺取法
  3. 哪些年我们不曾的考虑。。。
  4. SAP云平台部署应用时遇到的502 Updating service failed - Bad Gateway
  5. z17刷机miui12教程_《蝙蝠侠3百度影音》
  6. 数字资产价值巨大,GMQGroup深入布局挖掘数字财富
  7. gstat | 空间插值(四)——克里金插值之协同克里金和交叉验证
  8. C++_函数_函数的占位参数_函数重载---C++语言工作笔记034
  9. 2009-07-03 19:48 在linux中如何获得微秒精度的时间?-转
  10. 计算机打印服务总是自动关闭,XP系统Print spooler总是自动关闭的解决方法
  11. 您的主机不满足在启用 Hyper-V 或 Device/Credential Guard 的情况下运行 VMware Workstation 的最低要求(转载)
  12. Directshow的优点与缺点
  13. 西红柿炒鸡蛋怎么做(大厨教程 教你炒出饭店的味道)
  14. 柔性电子:灵敏电阻,基于高定向,独立的碳纳米管阵列的柔性压力传感器
  15. iTunes 备份损坏的解决办法
  16. ZYNQ之路--搞清楚Xilinx开发软件之间的关系
  17. excel怎样把一列中有相同的数据编同一个序号,且序号要递增
  18. html5页面是什么,什么是HTML?
  19. 企业微信机器人脚本python_Python 操控企业微信群机器人
  20. Postman设置中文

热门文章

  1. JavaScript:对象转换为字符串、字符串转换为对象
  2. JavaScript:数组、函数和对象
  3. C#:系统学习笔记(一)MVC基础篇
  4. Twitter数据抓取
  5. 批量根据实体类生成相关的类
  6. SLAM_数据集_EuRoC数据集简介与使用
  7. 论文笔记_S2D.57_2018-IROS_LIMO:激光雷达单目视觉里程计
  8. opencv图像分析与处理(13)- 彩色图像处理基础:彩色模型与伪彩色图像处理
  9. Hack_All_The_Things——探索IoT相关的攻击研究和渗透测试
  10. 关于C++中的继承感悟