引言
大家在开发中, 还有很多童鞋在写查询语句的时候, 习惯写下面这种不规范 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 小节 (原书第十五页内容如下):
此书也说明了, 两种方式在性能上几乎是没有差距的.
那为什么还是不推荐 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 指定列的方式, 可读性更强, 对于他们来说更好上手!
来源: https://www.cnblogs.com/rjzheng/p/9902911.html