不知道啥时候起,我越来越不想搞花里胡哨的事情了,这是不是老了啊
虽然我不做DBA,但是该知道的东西是要知道的


1、查询SQL尽量不要使用 select *,而是具体字段。

要粗略的理解这一点很简单,知道覆盖索引即可(字面意思)。

要稍微全面点的了解的话,建议了解一下“回表查询”和“覆盖索引”,我一会儿去写一篇。


2、如果可以明确知道查询结果的条数,或者只要最大/最小的一条记录,建议使用limit。

如果使用的查询条件是唯一索引那就无所谓。

加上limit之后,只要找到了足够的记录,就不会再往下扫描了。


3、应该避免在 where 子句中使用 or 来连接条件。

反例:

select XX from XXX where XXXX or XXXXX

正例1:

使用union all

select XX from XXX where XXXX
union all
select XX from XXX where XXXXX

使用 or 有可能会使得索引失效,从而全表扫描。

对于一边有索引,一边没有索引的情况更糟,会这样:全表扫描 + 索引扫描 + 合并。


4、优化 limit 分页

方案一:返回上次查询的最大记录
方案二:order by + 索引
方案三:在业务允许的情况下限制页数

5、优化like语句。


6、避免在索引列上使用内置函数。


7、避免在 where 子句中对字段进行表达式操作。


8、索引的最左匹配原则。


9、考虑在 where 、order by 涉及的列上建立索引。


10、exits 和 in 的合理使用。

这俩,功能都一样,挑一个顺手的一直用着就好。

来看看内部有什么不一样的。

select a from A where a in (select b from B);

这条语句可以这样拆解:

select b from B;
select a from A where A.a = B.b;

将A中的每一个数值拿去B里面比对。

那么:

select a from A where a exist(select b from B);

这条语句可以这样拆解:

select a from A;
select b from B where B.b = A.a;

将B里面的每一个数值拿去A里面比对。

基于MySQL小表驱动大表的优化原则(如果连接两次,每次做上百万次的比对;跟连接上百万次,每次做两个比对。很好选吧。)

对于我喜欢用 in 的人来说,数据量小的表就放右边子查询里咯。


11、尽量使用数字型字段。举个例子,我在设计带有固定字符名称的列时,直接使用了一个映射将列映射为代号,映射表直接存储在客户端上,放一份在redis中,如果客户端缓存被清空了可自取,备份一份在数据库中。

只要思想不滑坡,办法总比困难多、


12、尽量使用 varchar/nvarchar 取代 char/nchar。

首先变长字段存储空间小,可以节省存储空间。

其次对于查询来说,在一个相对较小的字段内搜素,效率更高。


13、如果使用的字段类型是字符串,where时一定用引号括起来,否则索引可能失效(mysql 会做隐式类型转换,你也不知道是索引方被转换配合你,还是你被转换配合索引了。)


14、使用 explain


15、对于这里面没有提到的,不要自己瞎猜,去验证。