1.索引优化
了解到mysql的innodb索引有两大类:
- 聚集索引:像innodb使用的主键索引,有且只有一个;数据是存在索引树的叶子节点上的
- 普通索引: 索引树的叶子节点上存的只有索引字段和主键值 当我们给表中字段建立索引之后,查询的字段非索引字段本身,则会有二次查询操作(回表)。
- 先通过普通索引查找到叶子节点上的主键值
- 再通过主键值查找数据行 解决措施:可以对查询字段建立联合索引去避免这个回表操作。
2.分页查询优化
对于使用limit字段,当limit偏移量越大时,查询的效率会降低,如:
limit 100000,10
此时的查询逻辑是:查询满足条件的前100010条数据,再去除前100000条。如果我们直接用select * 或者select 多个非索引字段的话,就会有二次回表查询操作:100010条数据就有100010次回表。
解决措施1:可以通过子查询来优化:先limit查询主键id,这样获取10个主键id就不用回表查询,再通过id去查询数据行,就可以了。如下:
select * from table where id in (select t.id from (select id from table limit 100000, 10) as t)
为啥要多一层呢?因为mysql不支持使用 LIMIT 子句的 IN/ALL/ANY/SOME 子查询。。
解决措施2:不用in,直接用inner join 关联查询。效率也很高
SELECT * from table t1 INNER JOIN (SELECT id from table LIMIT 100000, 10 ) as t2 on t1.id = t2.id
3. delete in ,update in 语句优化
我们经常用如下语句去删除指定主键id的数据行
delete t.* from table t where id in ()
这种语句通过explain分析可以看到是没有走索引的。但是把delete换成select就会走索引:mysql会自动优化select in 为inner join。但是mysql不会优化delete in。
解决措施:手动改造delete in 为 delete inner join 语句
4.联合索引最左匹配
当索引包含两个字段时,查询需要从最左字段开始查询,不然会导致索引失效。
5.隐式转换
加索引的字段是vachar,但是存的是数字时,查询条件直接用数字查询,会做隐式转换,导致索引失效。
6. 范围查询后索引失效
查询条件先查询范围 如 in > 等,后面的查询条件上的索引会失效。