优化流程
- 先用explain查询,看下是否用到了索引
- 排除缓存sql nocache
- 看下Extra是否存在回表,如果确实需要那么多列那就忽略,否则就考虑索引覆盖
- 查看下每个on语句是否都有索引建立
- 如果建立了,查看下两张表对应的列的字符集是否一样,因为mysql会自己做隐式转换
- 如果有排序字段,可以看情况用where后字段+order by字段建立联合索引
- 如果有联合索引,sql要按照最左匹配原则来改
- 查看你索引字段是否加了函数处理,如果加了不会走索引
- 5.6之后 索引下推 减少回表次数(之前是找索引时不会拿条件去判断,现在时找索引时会把条件一起去判断了)
Hash:
适合做等值查询,但是范围查询就不会走索引,所以可以用来存储一些静态数据(例如:年度账单之类的)
B+树
矮胖树,并且非叶子节点也会荣誉一份到叶子节点中,因为数据是最终存储到硬盘的,为了减少磁盘IO,所以用B+树,并且树结构也是有序的,可以做范围查询
回表
例如select * from table where name = 'XX', 我们找到name字段索引为XX的,然后得到id,再去主键索引找到id的记录,如果不想回表,可以用覆盖索引
覆盖索引
使用场景:
1. 全表count查询优化2. 列查询回表优化
3. 分页查询
上面的例子如果不查所有列,只查select id,那么就不会回表,因为name索引列已经找到了id,覆盖索引可以减少树的搜索次数
最左匹配原则
索引列可以有一个,也可以有多个,例如(a,b,c,d)联合索引,遇到范围(>,<,between,like左匹配)查询就不能进一步匹配了。
小技巧
sql查询的时候有可能会有缓存,在sql语句前加个SQL_NO_CACHE就能知道真正的执行时间
select SQL_NO_CACHE * from table