【原创】Mysql中select的正确姿式

引言

你们在开发中,还有不少童鞋在写查询语句的时候,习惯写下面这种不规范sqlmysql

select * from table

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

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

我也知道,这些童鞋是图方便,毕竟再敲一堆的列名,嫌麻烦!
大家上班能够问问本身的同事sql

你:“xx,知道select *和select全部字段的区别么?
同事:"额。。额。。额。。"
留下的只有尴尬的笑容!数据库

我也知道,不少人至今都没有搞懂select *selct 全部字段的区别
所以,我开一文来讲明一下。另外,我选的是本身最熟悉的mysql数据库,此文的结论在oralce,sqlserver上是否成立,博主没作过测试。网络

正文

(select全部字段)性能高?

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

“*” 表示通配全部字段,在SQL的机制里,须要先识别统计全部字段再进行下一步。
明确指定字段的话,会减小上述的操做,因此效率有所提高。sqlserver

然而,实际上呢?效率是相差不大的!。
取博客
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小节(原书第十五页内容以下):
image
此书也说明了,两种方式在性能上几乎是没有差距的。
那为何仍是不推荐select * ?ui

网络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 指定列的方式,可读性更强,对于他们来讲更好上手!

相关文章
相关标签/搜索