如果查询字段是字符型,WHERE条件后建议使用’’,否则导致索引失效

未加’’

  1. EXPLAIN SELECT * FROM student_basic_info sbi WHERE sbi.id = 1;

image.png

加’’

  1. EXPLAIN SELECT * FROM student_basic_info sbi WHERE sbi.id = '1';

image.png

优化LIKE SQL语句

%位置

查询字段前后都加%,导致索引失效

  1. EXPLAIN SELECT * FROM student_basic_info WHERE stuinfo_name LIKE '%张%';

image.png

查询字段后加%,索引生效

  1. EXPLAIN SELECT * FROM student_basic_info WHERE stuinfo_name LIKE '张%';

image.png

查询列应该使用具体字段,而不用*

只取所需要的字段,节省资源,减少网络开销。SELECT * 进行查询时,很可能就不会使用覆盖索引,导致回表查询。

  1. 反例
  2. SELECT * FROM student_basic_info;
  3. 正例
  4. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info;

如果知道查询结果只有一条或者只要最大、最小的一条记录,建议使用LIMIT 1

SQL语句加上LIMIT 1之后,只要找到一条对应的记录,就不会继续向下扫描了,效率大大提高。如果所查询列是唯一索引,是没有必要加LIMIT 1,加LIMIT 1是为了防止全表扫描,从而提高性能。

  1. 反例
  2. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_name = '张三';
  3. 正例
  4. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_name = '张三' LIMIT 1;

应尽量避免在WHERE条件字句中使用OR来连接条件

使用OR可能会导致索引失效,而从导致全表扫描
对于OR + 没有索引的stuinfo_age这种情况,假设它走了stuinfo_name的索引,但是走到stuinfo_age查询条件的时候,它还得进行全表扫描,额就是需要三步过程:全表扫描+索引扫描+合并,如果它一开始就走全表扫描,直接一遍扫描就可以。MySQL是有自己的优化器的,处于效率与成本考虑,遇到OR条件,索引可能失效,看起来也合情合理。

  1. 反例
  2. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_name = '张三' OR sbi.stuinfo_age = '12';
  3. 正例
  4. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_name = '张三'
  5. UNION ALL
  6. SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_age = '12';

应尽量避免在WHERE字句中对字段进行表达式操作,这会导致系统放弃索引而进行全表扫描

  1. 反例
  2. EXPLAIN SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_age + 1 = 11;
  3. 正例
  4. EXPLAIN SELECT id,stuinfo_name,stuinfo_address FROM student_basic_info sbi WHERE sbi.stuinfo_age = 12;

慎用DISTINCT关键字

DISTINCT关键字一般用来过滤重复记录,以返回不重复的记录。
在查询一个字段或者很少字段的情况下使用,给查询带来优化效果,在查询字段很多的情况下,却会大大降低查询效率。
带DISTINCT的SQL语句CPU时间和占用时间都高于不带DISTINCT的语句。因为当查询很多字段时,如果使用DISTINCT,数据库引擎就会对数据进行比较,过滤掉重复数据,然后这个比较、过滤的过程会占用系统资源,CPU时间。

  1. 反例
  2. SELECT DISTINCT * FROM student_basic_info sbi;
  3. 正例
  4. SELECT DISTINCT sbi.id,sbi.stuinfo_address FROM student_basic_info sbi;

WHERE字句中考虑使用默认值代替null

并不是说使用IS NULL或者IS NOT NULL就会不走索引,这跟MySQL版本以及查询成本都有关。
如果MySQL优化器发现,走索引比不走索引成本要高,肯定会放弃索引。
条件!=、<>、IS NULL 、IS NOT NULL经常被认为会让索引失效,其实是因为一般情况下,查询的成本高,优化器主动放弃的。
如果把NULL值,换成默认值,很多时候让走索引成为可能。

尽量不要超过5个表以上的连接

  • 表连接越多,编译的时间和开销也就越大;
  • 把表连接拆成开销较小的几个执行,可读性更高;
  • 如果一定需要连接很多表才能得到数据,那么意味这是一个糟糕的设计。