性能下降SQL慢
- 查询语句写的烂
- 索引失效
- 单值索引
- 复合索引
- 关联查询太多join(设计缺陷或不得已的需求)
- 服务器调优及各个参数设置(缓冲、线程数等)
索引优化
单表
建立表
两表
建立表
总结:左连接建右表,右连接建左表。
理由:以左连接为例,左表的信息全都有,所以右表需要查找,所以建立右表index。
三表
建表SQL
总结:Join语句的优化
- 尽可能减少Join语句中的NestedLoop的循环总次数:“永远用小结果集驱动大的结果集”。
- 优先优化NestedLoop的内层循环。
- 保证Join语句中被驱动表上Join条件字段已经被索引。
- 当无法保证被驱动表的Join条件字段被索引且内存资源充足的前提下,不要太吝惜JoinBuffer的设置。
索引失效
建表
案例(索引失效)
- 全值匹配我最爱
也即是对建立的复合索引全部使用到,则能保证极高的性能 - 最佳左前缀法则:
如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列。(带头大哥不能死,中间兄弟不能断) - 索引不操作
不在索引列上作任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
- 存储引擎不能使用索引中范围条件右边的索引列
为保证性能,中间兄弟别搞范围,要搞等值 - 尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *
所谓覆盖索引是指索引的列刚和能够从建立的复合索引中来读取而无需读取数据库
按需取数据,用多少取多少,尽量与索引一致
Extra中出现了using index很好!
使用select *的一个潜在问题就是让覆盖索引失效
- mysql在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描
- is null,is not null也无法使用索引
- like以通配符开头(‘%abc…’)mysql索引失效会变成全表扫描的操作
like%加右边,索引不会失效
问题:解决like ‘%字符串%’时索引不被使用的方法?
- 字符串不加单引号索引失效
该问题同问题3,是索引列上做了类型转换!
VARCHAR类型绝对不能失去单引号
- 少用or,用它来连接时会索引失效
小总结
优化总结口诀:
全值匹配我最爱,最左前缀要遵守;带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
LIKE百分写最右,覆盖索引不写星;
不等空值还有or,索引失效要少用;
VAR引号不可丢,SQL高级也不难!