mysql优化工具:
- 索引优化使用explain查看执行计划;
- 使用trace工具可以查看成本扫描;
优化原则:
- 查询的字段尽量被索引覆盖
- 遵循最左前缀原则:使用联合索引查询要从最左前列开始,不跳过索引中的列。
- 不要在索引列上做任何操作,例如,函数,手动/自动类型转换。
- 联合索引的范围查找右边的列不走索引
- 尽量使用覆盖索引,减少select*语句
- !=无法使用索引
- is null,is not null一般情况下也无法使用索引,因为null在索引树中,会集中在左端/右端存储。
- like后模糊匹配走索引
- 字符串不加单引号会导致类型转换,导致索引失效
- in or,会根据检索比例,表大小等因素评估是否使用索引; 表小不走索引; in条数过多,不走索引。
- 范围太小/太大,会导致索引失效 太小/太小都会扫全表,避免回表,所以将范围控制在合适的范围内,或使用覆盖索引优化。
索引下推
Mysql在5.6开始,引入索引下推,like后模糊匹配索引不会断,会进行后续索引列的过滤之后,再进行回表。
- 联合索引第1个字段使用范围查找,一定不会走索引
- 确定更有方案可以强制走索引
- 可以使用覆盖索引优化
- in or表小不走索引; in条数过多,不走索引。
- like后模糊匹配,通常情况下走索引
但是如果匹配后查询的结果集大于某个阈值,且还要回表,则不会走索引。
orderby,groupby优化
- where和orderby组合要符合最左前缀原则
- 尽量使用where将范围缩小,优先where优化
- 使用覆盖索引优化
- order by x desc需要在创建索引时声明
- 能使用where解决的,就不要用having
- group by优化原理同order by
- group by会先排序,后分组,为避免显式/隐式排序,可以使用order by null禁止排序。
索引设计原则
- 代码先行,索引后上
- 尽量使用2个左右的联合索引,覆盖大多数业务场景
- 不要在小基数上建立索引
- 长字符串可以采用前缀索引
- where和order by冲突时,优先where
- 可以开启慢sql日志,针对慢sql进行优化
分页优化
- mysql会将前面的行都扫描出来,再扫描继续扫描需要的行数
所以可以使用id>start直接定位,前提是连续自增,使用条件比较苛刻 - 使用where条件检索出id,然后in(ids)查询
表连接优化
- 小表驱动大表,索引字段建立索引
- 连接字段有索引,使用嵌套连接查询,将驱动表查询结果集拿到内存bufferpool,拿出1行,去用索引定位被驱动表匹配的数据,然后拿出第2行,直到结果集匹配完;
连接字段无索引,使用基于块的嵌套连接查询,将驱动表的数据缓存到joinbuffer,然后逐行拿出被驱动表的数据到内存匹配;
驱动表的数据在1个joinbuffer存不下,会进行分段存储。
in和exists优化
- in先里后外,exists先外后里
保证先查询的是小表。
count优化
- mysql5.7之后,字段没有索引,count(*)=count(1)=count(0)>count(id)>count(字段)
字段有索引,count(*)=count(1)=count(0)>count(字段)>count(id) - count(字段/id),会遍历普通索引树/主键索引树,取出字段/id,判空,逐行累加
count(*),count(1),count(0),遍历整表,不数据,不判空,逐行累加。 - myisam不支持事务,不加条件可以直接返回总行数;
innodb因为有mvcc机制,不同事务看到的行数可能不同,所以需要实时累计。