多使用 explain 解析一下 sql 语句的索引使用情况
type-保证查询至少达到 range 级别(const、eq_reg、ref、range、index和ALL)
extra-看到有 Using filesort, Using temporary 查询需要优化
key-看到使用索引是哪一个
ken_len-使用的索引的长度

以及,如果发现 SQL 查询响应很慢的时候,可以通过

select * from information_schema.`PROCESSLIST` where info is not null;

去看看,到底是哪条语句出现响应或者等待慢的情况,然后根据该语句独立进行优化

单表
1.使用复合索引时,要注意索引的顺序(where后面的顺序和select的字段顺序),需要和复合索引的顺序一致,不要跨列使用(where和order by拼起来不要跨列使用)
2.使用查询的时候,尽可能让索引生效(改变where后面的顺序,原理和1一致,把可能让索引失效的查询(比如 in 的范围查询)放到最后面)
3.对于不再使用的索引,需要进行删除,避免索引之间的干扰(我想用A索引,实际用了B索引)

多表
1.索引增加的位置为经常使用的字段上,如表关联的条件 on a.xx=b.xx 中的 a.xx字段,(根据小表驱动大表,小表放左边,大表放右边)
2.(left outer join)左外链接给左表加索引,(right outer join)右外链接给右表加索引
3.where 后面的查询条件进行加索引

其他优化方法
1.exist 和 in
如果主查询的数据集大,使用 in 效率高
如果子查询的数据集大,使用 exist 效率高(将主查询的结果,放到子查询结果中进行条件校验)

2.order by
using filesort 有两种算法,双路排序,单路排序(根据IO次数)
MySQL4.1之前 默认使用 双路排序(扫描两次磁盘,1.从磁盘读取排序字段 2.扫描其他字段 )
MySQL4.1之后 默认使用 单路排序(只读取一次全部字段,在buffer中进行排序,单不一定是真的单路,可能多次IO,因为如果数据量特别大,会进行分片读取,可考虑调大buffer大小)

set max_length_for_sort_data = 1024 单位byte

如果该值太低(需要排序的列的总大小超过了该值的字节数),MySQL会从单路切换为双路
也就是
1)选择使用单路,双路,调整buffer的容量大小
2)避免 select * …(对索引也有好处,可索引覆盖)
3)保证全部的排序字段排序的一致性(都是升序或者降序)

3.慢查询日志
MySQL提供的一种日志记录,用于记录MySQL响应时间超过阈值的SQL语句(long_query 10s),默认是关闭的
开发调优时进行打开,正式环境时关闭
检查是否开启了慢查询日志

show variables like '%slow_query_log%'

临时开启(MySQL一退出就关闭)

set global slow_query_log=1 
exit
service mysql restart

永久开启
MySQL配置文件进行修改

[mysqld]
slow_query_log=1
slow_query_log_file=/path/localhost-slow.log

慢查询响应时间阈值

show variables like '%slow_query_time%'

临时设置阈值

set global slow_query_time=5
exit 重启就生效

永久设置阈值

[mysqld]
slow_query_time=5 

查询超过慢查询阈值的SQL语句的数量

show global status like '%slow_queries%'

然后通过日志查询具体的慢SQL(mysqldumpslow)