我相信“严禁在代码中使用 select*”这句话大家应该都不陌生,很多公司都会三令五申强调这一点,就连福报厂的 Java 开发手册也明确表示不得使用“*”作为查询。如果我在 code review 中发现有小伙伴这么写代码,肯定不会让他过试用期。这可不是我狠,而是互联网 SQL 语句的规则,因为这关系到整个系统的性能,在很多面试场合也都会被问到。
那为啥要禁用 select *呢?可能有些小伙伴会说,用 select查的是所有字段,数据量大了自然就会影响性能。确实,我们都知道数据是存储在磁盘上的,查所有字段肯定会增加磁盘 IO 的开销。如果这些字段中包含一些大字段,比如 text、blob 等,读取就会很慢。另外,从应用服务器获取数据库服务器的数据本身也会有一定的网络时延,查的越多速度肯定越慢。查得慢,线程释放就慢,会影响其他的查询线程,自然整体的性能就会受到影响。
还有一个重要原因是无法使用覆盖索引。比如说你要查询的字段碰巧设置了索引,这时候就可以直接从索引的 B+树中获取数据,基于 B+树的检索速度是很快的。但如果偏偏用了 select*,又不可能每个字段都建索引,那就没法直接从索引树里面查找数据,就得从磁盘上面去查找完整记录,这就是常说的回表。无法利用覆盖索引,查询性能就大打折扣了。
其实换个思路想,前面做了很多性能优化的策略,比如分库分表等,结果还用 select*,这就像进了一个高楼大厦,装修豪华、设计人性化,结果地基用的是泥糊的,再怎么优化性能、提高并发也都无济于事。