首先,任何优化都离不开“时间”、“空间”的权衡。笔者看来,MySQL的优化可以分为:“内部优化”、“外部优化”两部分。

一、内部优化

MySQL内部优化指定是它本身的优化手段,可以大致分为包括“结构”、“配置”两部分内容。

(一)结构

1. 字段

  • 类型:合理选择int、bigint、tinyint、float等字段
  • 长度/大小:在预留一定空间的前提下,按需选择字段长度
  • 约束:能加not null、unsigned的就加上
  • 其他说明:

2. 索引

MySQL索引有:FULLTEXT、SPATIAL、NORMAL、UNIQUE等类型,我们平时用的一般是后两者,此处重点介绍它们。

此处需要引入一个概念:“索引选择性”。索引选择性=索引所在字段不同值行数/该字段总行数。举例说明:会员表有1000条会员数据,性别字段有男、女、未知共3中情况,其索引选择性=3/1000=0.003,很低。而手机号字段的索引选择性接近1000/1000=1,非常高。

(1)适合建索引的情况

  • 索引选择性高的字段,如:手机号、条码号、唯一编码等
  • 具有外键特征的字段,如:用户表中的账号ID、支付表中的订单ID等
  • 常作为查询条件的字段,如:订单表中的买家ID、退款表中的退款流水号等

(2)不适合建索引的情况

  • 索引选择性低的字段,如:性别、某状态、某类型等具有枚举特征的字段
  • 长文本类型字段,如:图片URL、评论内容、个性签名等。需要注意的是,字段 like '%内容%'并不能发挥索引作用,而 like '内容%'右模糊可以发挥索引作用

(二)配置

MySQL有许多系统调优参数,供我们自定义配置,本文不展开介绍,感兴趣的读者可以查阅其他资料。


二、外部优化

外部优化实际上指的是操作MySQL的方式优化,大部分情况下指的是SQL语局的优化。而SQL语句优化的重点在查询语句上,即DQL。另外,合理使用批量操作也减少数据库连接次数,提升性能

(一)查询

  1. 尽量避免select *
  2. where子句中,快速过滤数据的条件放在前面
  3. where子句中,尽量避免使用!=和<>操作符,这会导致引擎放弃索引而查全表
  4. where子句中,匹配条件采用同类型,整形和字符型虽然兼容但是效率会减低
  5. where子句中,避免操作结果作为比较条件,如select * from student where score + 10 > 90;
  6. 尽量避免子查询,能用连表查询替代尽量使用连表查询,避免出现n+1问题
  7. 明确查询结构只有1条时,可以加上limit 1终结扫表
  8. 对于连续范围取值,可以使用between替代in

(二)批量操作

1. 批量插入

insert into table(column1, column2, ...) values (value1, value2, ...), (value1, value2, ...),(value1, value2, ...)

2. 批量更新

本处重点介绍更新条件不同且更新字段值也不同的批量更新。

update table set column = value1 where id = 1; update table set column = value2 where id = 2;...

注意:程序中与数据库的连接需要开启支持分号;间隔的批量语法:&allowMultiQueries=true

3. 批量删除

此处通过where字句控制即可。