不知道啥时候起,我越来越不想搞花里胡哨的事情了,这是不是老了啊 虽然我不做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、对于这里面没有提到的,不要自己瞎猜,去验证。