索引设计原则
1. 代码先行,索引后上
一般应该等到主体业务功能开发完毕,把涉及到该表相关 SQL 都要拿出来分析之后再建立索引。
2. 联合索引尽量覆盖条件
可以设计一个或者两三个联合索引(尽量少建单值索引),让每一个联合索引都尽量去包含 SQL 语句里的 WHERE、ORDER BY 、GROUP BY 的字段,还要确保这些联合索引的字段顺序尽量满足 SQL 查询的最左前缀原则。
3. 不要在小基数字段上建立索引
索引基数是指这个字段在表里总共有多少个不同的值,比如一张表总共 100 万行记录,其中有个性别字段,其值不是男就是女,那么该字段的基数就是 2。 如果对这种小基数字段建立索引的话,那还不如全表扫描,因为你的索引树里只包含男和女两种值,办法进行快速的二分查找,那用索引就没有太大的意义。 一般建立索引,尽量使用那些基数比较大的字段,就是值比较多的字段,那么才能发挥出 B+ 树快速二分查找的优势。
4. 长字符串可以采用前缀索引
尽量对字段类型较小的列设计索引,比如 tinyint 之类的,因为字段类型较小的话,占用磁盘空间也会比较小,此时你在搜索的时候性能也会好一点。 当然,这个所谓的字段类型小一点的列,也不是绝对的。很多时候你就是要针对 varchar(255) 这种字段建立索引,哪怕多占用一些磁盘空间也是有必要的 对于这种 varchar(255) 的字段可能会比较占用磁盘空间,可以稍微优化下,比如针对这个字段的 前20 个字符建立索引,就是说,对这个字段里的每个值的 前20 个字符放在索引树里,
类似于 KEY index(name(20), age, position)
此时你在 WHERE 条件里搜索的时候,如果是根据 name 字段来搜索,那么此时就会先到索引树里根据 name 字段的 前20 个字符去搜索,定位到之后 前20 个字符的前缀匹配的部分数据之后,再回到聚簇索引提取出来完整的 name 字段值进行比对。但是假如你要是 ORDER BY name ,那么此时你的 name 因为在索树里仅仅包含了 前20 个字符,所以这个排序是没法用上索引的,GROUP BY 也是同理。
5. WHERE 与 ORDER BY 冲突时优先 WHERE
在 WHERE 和 ORDER BY 出现索引设计冲突时,到底是针对 WHERE去设计索引,还是针对 ORDER BY 设计索引? 到底是让 WHERE 去用上索引,还是让 ORDER BY 用上索引? 一般这种时候往往都是让 WHERE 条件去使用索引来快速筛选出来一部分指定的数据,接着再进行排序。因为大多数情况基于索引进行 WHERE 筛选往往可以最快速度筛选出你要的少部分数据,然后做排序的成本可能会小很多。
6. 基于慢 SQL 查询做优化
可以根据监控后台的一些慢 SQL ,针对这些慢 SQL 查询做特定的索引优化。