mysql中使用select的正确姿势

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> mysql中使用select的正确姿势

引言

大家在开发中,还有很多童鞋在写查询语句的时候,习惯写下面这种不规范sql


select * from table

而不写成下面的这种规范方式


select col1,col2,...,coln from table

我也知道,这些童鞋是图方便,毕竟再敲一堆的列名,嫌麻烦!
你们上班可以问问自己的同事

**你:“xx,知道select *和select所有字段的区别么?    **
**同事:”额。。额。。额。。”   **
留下的只有尴尬的笑容!

**同事:”额。。额。。额。。”   **

我也知道,很多人至今都没有搞懂 select * selct 所有字段的区别
因此,我开一文来说明一下。另外,我选的是自己最熟悉的 mysql数据库,此文的结论在 oralce, sqlserver上是否成立,博主没做过测试。

正文

(select所有字段)性能高?

网络上流传着一种说法说是

“*” 表示通配所有字段,在SQL的机制里,需要先识别统计所有字段再进行下一步。 明确指定字段的话,会减少上述的操作,所以效率有所提升。

然而,实际上呢?效率是相差不大的!。
取博客
http://flysnowxf.iteye.com/blog/1125032
的测试结果
mysql 5.1.37
表记录数41,547,002,即4000w行
使用远程客户端取1000条数据,统计时间:


SELECT * FROM `dmsp`.`dmsp_dimension_content` LIMIT 0, 1000;  

时间2.218s,网络消耗0.547s


SELECT `id`, `appid`, `aop`, `t`, `uid`, `sid`, `pid`, `pname`, 
`bid`, `bname`, `ptype`, `sm`, `sv`, `bt`, `national`, `area`,
`ov` FROM `dmsp`.`dmsp_dimension_content` LIMIT 0, 1000;  

取出所有字段,时间2.250s,网络消耗0.578s
可以看出,这二者的时间差几乎可以忽略,另外还有一本书上的内容也可以佐证我的话。
《SQL CookBook》第一章 检索记录中1.1小节(原书第十五页内容如下):

mysql中使用select的正确姿势

此书也说明了,两种方式在性能上几乎是没有差距的。
那为什么还是不推荐select * ?

网络IO问题

很多文章里说什么,会带来额外的内存、磁盘、cpu的开销。对此,我有自己的观点。我觉得这不是主要原因。主要原因是带来了额外的网络开销。
在一个系统中,内存、磁盘、cpu的开销,不过是微秒级。造成系统的延迟的重头戏是网络开销。网络开销可能带来秒级的延迟。当然,如果你的应用程序和数据库是在同一台机器上的,那当我没说这句话!
select *会查询出不需要的、额外的数据,那么这些额外的数据在网络上进行传输,必定会造成性能延迟。假设你的 table中,有一个列的类型为 binary。此时,你的 select *操作,就会十分缓慢,并且会造成额外的网络开销。

索引问题

仔细看下面的两句sql


select col1 from table;
select * from table;

如果col1字段包含索引信息,那么此时,这两句的sql执行时间可能会有几十上百倍的差异。
在col1字段有索引的情况下,mysql是可以不用读data,直接使用index里面的值就返回结果的。但是一旦用了 select *,就会有其他列需要读取,这时在读完index以后还需要去读data才会返回结果。这样就造成了额外的性能开销。

ps:我不想在这里扯什么覆盖索引,辅助索引的概念。其实要讲的很专业,扯一堆高大上的名词,我也可以。只是这样徒增读者的理解难度,尽量用通俗的方式来讲。

扩展性问题

有的人会觉得

使用select * ,这样在增加列的时候,不用改sql,方便!

然而实际上,你的sql是不用改了,但是对你的程序代码是有很大的影响的!
身为一名21世纪的优良程序员,我们是不能获取自己需要的东西的!你因为一时高兴,执行了 select *,如果增加或删除列,会对你的代码有着极大的影响。
反过来,如果你 select 指定列,只获取自己需要的几列,表结构的修改,对你代码的影响就会小很多。相比之下,风险就没有那么大了!
另外就是,对于其他人接手你项目的人来说,看到 select 指定列的方式,可读性更强,对于他们来说更好上手!

往期精彩

原文始发于微信公众号( 打杂的ZRJ ):

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> mysql中使用select的正确姿势


 上一篇
Mysql十大经典错误案例,你遇到过几个? Mysql十大经典错误案例,你遇到过几个?
作者:张甦出处:http://blog.51cto.com/sumongodb/1949426 今天就给大家列举 MySQL 数据库中,最经典的十大错误案例,并附有处理问题的解决思路和方法,希望能给刚入行,或数据库爱好者一些帮助。
下一篇 
MySQL(Innodb)索引的原理 MySQL(Innodb)索引的原理
引言回想四年前,我在学习mysql的索引这块的时候,老师在讲索引的时候,是像下面这么说的 索引就像一本书的目录。而当用户通过索引查找数据时,就好比用户通过目录查询某章节的某个知识点。这样就帮助用户有效地提高了查找速度。所以,使用索引可以