1.索引
经常查询的,经常修改的不建,like 前%索引失效.
2.Explain查新执行计划
-
字段
-
- table:表名.
- type:重要,表示连接使用了那种类型.从好到差:const,eq_reg,ref,range,index和all.(至少range以上).
- possible_keys:可能应用的索引.
- key:实际使用的索引.
- key_len:索引长度,不损失精度情况下,越小越好.
- rowsmysql认为的检索行数.
3.子查询优化
in改为join,distinct去重
4.limit优化
5.数据库结构
- 合适的数据类型
- 范式
- 垂直拆分
- 水平拆分
6.语句优化
- 避免使用in 和 not in,效率低,因not in 不能命中索引,改成 not exists好很多。in值不应过多。
select * from 表A where id in (select id from 表B)
select * from 表A where exists(select * from 表B where 表B.id=表A.id)
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
- select指明字段。
- 排序没用到索引,就少排序。
- or前后有一个没索引,索引失效。
- 不要在列上进行计算。,将导致索引失效而全表扫描。
- 索引不会包含有null值的列。不要让字段默认值为null。
- union 去重,union all不去重。尽量union all去重。
- where子句中不要进行null判断,引擎会放弃索引扫描器全表。
- where子句对字段进行表达式操作。
select user_id,user_project from user_base where age*2=36;(低效)
select user_id,user_project from user_base where age=36/2;(建议)
- 避免隐式类型转换(索引失效)
where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型。
- force index强制走正确的索引