MySQL --- 读书笔记 --- 索引(3)
从几个方面优化数据库
- 索引失效
- 关联查询太多
- 服务器调优
- 数据过多
优化技术分为
- 物理优化:主要是索引的使用
- 逻辑优化:SQL的等价变换
索引失效案例
MySQL提高性能的一个最有效的方式就是对数据表设计有效的索引
,但是最终用不用索引,是优化器决定的,它不是根据规则
,也不是根据语义
,而是基于开销(cost)
,怎么开销小怎么做。SQL语句是否使用索引,跟数据库版本、数据量、数据选择度都有关系。
1. 全值匹配
会尽可能多的匹配最佳索引,当WHERE
条件较多时,匹配更多的联合索引,可以使得回表时,搜索更少的记录
2. 最佳左前缀法则
对于多列索引,过滤条件要使用索引必须按照索引建立时的顺序,依次满足,一旦跳过某个字段,索引后面的字段都无法使用。如果查询条件中没有使用这些字段中的第一个字段,联合索引不会被使用
3. 主键插入顺序
在聚簇索引中,记录是按照主键顺序存储,一个页满了,新建一个页继续插入,如果插入的主键忽大忽小,那么在一个页满了之后,再想从中间插入一条记录,就会发生页分裂
和记录移位
的情况,这意味着性能损耗
。所以最好让插入的主键依次递增
4. 计算、函数、类型转换导致索引失效
5. 范围条件右边的列索引失效
CREATE INDEX index_a_c_n ON S1(age,classId,name)
EXPLAIN SELECT * FROM S1 WHERE age=3 AND classsId > 20 AND `name`='abc'
- 只使用了前两个索引列,最后一个没有使用
- 可以在创建索引时,就考虑这种情况,将范围条件放在联合索引的最后,这样就可以使用全索引
6. 不等于判断-索引失效
7. is null可以使用索引,is not null无法使用索引
8. like以通配符%开头索引失效
9. OR 前后存在非索引的列,索引失效
OR前后的两个条件中的列都是索引时,查询中才使用索引
10. 数据库和表的字符集统一使用utf8mb4
兼容性更好,统一字符集可以避免由于字符集转换产生乱码,不同字符集进行比较之前需要进行转换,会造成索引失效
一般性建议
- 对于单列索引,尽量选择针对当前query过滤性更好的索引
- 在选择联合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,越靠前越好
- 在选择联合索引的时候,尽量选择能够包含当前query中的where子句中更多字段的索引
- 在选择联合索引的时候,如果某个字段出现范围查询,尽量把这个字段放在索引次序的最后