SELECT * FROM GIRLS WHERE AGE BETWEEN 20 AND 24 ...

阿粉最近看到一张图,如下所示,原本只是一个搞笑的图,但是在阿粉看来这分明是个渣男啊!一句普通的 SQL 语句SELECT * FROM GIRLS WHERE AGE BETWEEN 20 AND 24 AND BOYFRIEND IS NULL,也有很多内涵!

什么?没看出来?来,阿粉带你品品。

未限制返回的数量

这是个大问题啊,竟然没有设置 LIMIT 1,你是想找几个女朋友?

设置 LIMIT 1 MySQL 数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

一般大家在写列表查询的时候,都是分页查询的,否则在数据量很大的时候,全部查询出来,肯定会内存爆棚的。常规的分页语句想必大家都知道,是使用SELECT a,b,c FROM table WHERE id = xxx ORDER BY xx LIMIT OFFSET, SIZE;但是这种分页查询方式在数据量庞大的时候效率也是很低的,所以当在 MySQL 数据量庞大的时候可以通过改成子查询的方式来进行优化。

比如当我们执行SELECT * FROM users WHERE age BETWEEN 20 AND 24 ORDER BY id LIMIT 10000000, 10; 的时候这种情况分页查询的效率也是很低的,所以我们可以改成这种形式

1
2
SELECT * FROM users WHERE  id >=  
(SELECT id FROM users  WHERE age BETWEEN 20 AND 24 ORDER BY id LIMIT 10000000, 1) LIMIT 10 

这种写法因为子查询的 id 是在索引上面进行扫描的,所以查询效率会快很多,然后在通过 limit 10 就可以获取到相应的数据。

哼,渣男无疑了吧!

禁止使用 select *

骑着单车去酒吧——该省省,该花花。要什么就挑什么,怎么能啥都要!

首先看过阿粉之前提到的阿里巴巴 Java 规范手册的朋友,肯定知道在数据库相关模块有如下的强制要求,说的是在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。如下图所示

这里还没有看过阿里巴巴 Java 规范手册的,可以在公众号后台回复【Java】获取华山版和其他资料。

文档中给出的说明有三点,分明是

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

这几点还是比较好理解的,阿粉这里想说明一下的是特别是在分库分表的时候,如果我们在发布的时候有数据库结构的变更,一般都是先升级数据库,然后再更新代码,这里我们一定要等待所有的表的结构都更新完了再更新代码,不然会导致代码逻辑是新的,但是表结构还是旧的,这种情况出现就会有问题。不过这种情况并不常见,一般会当代码和数据库有中间有其他中间件的时候,如果中间件处理的不合理才会遇到。

哼,贪心了吧!

尽可能设置充足的条件

一般我们在创建表的时候,都会要求设置字段的默认值,这样在查询的时候就可以使用默认值进行查询,尽量避免在 where 子句中对字段进行 null 值判断,创建表时一般会设置 NOT NULL 然后再设置如 0 或者 -1 作为默认值。然后阿粉默默的问一句,只看 AGEBOYFRIEND 这两个条件就够了吗?不考虑下是否已婚了?条件都加上了可以更加精确的查到所需的数据。

Java Geek Tech wechat
欢迎订阅 Java 极客技术,这里分享关于 Java 的一切。