转载自网络,有两条忘了记,所以就17条,侵删
1、用 EXPLAIN 查看 SQL 执行计划,找出优化点
2、SQL 语句中 in 包含的值不应过多
- 因为 MySQL 会用数组来保存 in 中字段数据,越多字段占用的内存越多,必要时(符合需求时)尽量在索引字段做 between and 来替代 in
3、SQL 中 select 后面必须指明要查询的字段,减少不必要的消耗,并且指明字段更大可能使用到联合索引,避免回表
4、只需要一条数据时,加 limit 1 限制,这是为了在 EXPLAIN 中 type 列达到 const 类型,尽量避免 All (全表扫描)
5、如果排序字段没有用到索引,尽量不要排序,或给经常用于排序的列加索引
6、不使用 order by RAND()
7、区分 in、exist 和 not in、not exist :
- exist 先查外层查询,后查内层查询,适合外层表小的情况;
- in 先查内层查询,后查外层查询,适合内层表小的情况
8、合理使用分页方式以提高效率
limit X, Y == limit Y offset X(查询方式为:全表扫描到第 X 条,开始查出 Y 条记录),从查询方式就可以看出表变大时查询效率会很糟糕。
考虑优化方式(前提是使用了自增id,所以没有充分理由请尽量使用自增id):
- 原查询:
select id, name from product limit 866613, 20
- 优化:获取上一页最大 id 是 866612
select id, name from product where id > 866612 limit 20
9、分段查询
一次查询分段跨度过大时,查询速度缓慢,可考虑在程序中分开多次将大分段分开多次查询,最后做汇总
10、避免在 where 子句中进行 null 值判断
在 where 子句中进行 null 判断会导致引擎放弃使用索引转而进行全表扫描
11、尽量避免 like "%xxx" 形式的模糊查询,这样会导致索引失效二进行全表扫描
12、避免在 where 子句中对字段进行表达式操作,会导致查询时放弃索引进行全表扫描
例如: select * from A where age*2 = 36 改为 select * from A where age = 36/2
13、避免使用隐士类型转换,先确定好字段类型,使用对应类型查库
14、对于联合索引,要遵循最左原则
15、必要时使用 force Index 来强制使用索引,因为 mysql 优化器有时会选错索引
16、注意联合索引时的范围查询
使用联合索引时,如果存在范围查询,会造成索引失效
17、join 优化
无需外联时尽量使用内联 inner join
left join 会选取左边表作驱动表
right join 会选取右边表作驱动表
inner join 会选取较小的表做驱动表
请选取小表作驱动表,前提是可以使用被驱动表的索引