mysql索引建立方案&优化方案
阿昌 Java小菜鸡
# 索引建立方案
  • 索引最好是让你的各个where、orderby和group by后面跟的字段都是联合索引的最左侧开始的部分字段,这样他们都能用上索引(索引顺序一致

  • 不要为字段基础小的字段建立索引,如只有1、0值

  • 建立索引,尽量使用那些基数比较大的字段,就是值比较多的字段,那么才能发挥出B+树快速二分查找的优势来。

  • 尽量是对那些字段的类型比较小的列来设计索引,比如说什么tinyint之类的,因为他的字段类型比较小,说明这个字段自己本身的值占用磁盘空间小,此时你在搜索的时候性能也会比较好一点。

  • 建立出来的索引其实类似于KEY my_index(name(20),age,course);假设name是varchar(255)类型的,但是在索引树里你对name的值仅仅提取前20个字符而已。

    • where条件里搜索的时候就可以使用前20个字符在索引中搜索
    • 但order by name、group by就不行
  • 因为你插入的数据值可能根本不是按照顺序来的,很可能会导致索引树里的某个页就会自动分裂,这个页分裂的过程就很耗费时间,因此一般让大家设计索引别太多,建议两三个联合索引就应该覆盖掉你这个表的全部查询了。

  • 建议主键一定是自增的,别用UUID之类的,因为主键自增,那么起码你的聚簇索引不会频繁的分裂,主键值都是有序的,就会自然的新增一个页而已,但是如果你用的是UUID,那么也会导致聚簇索引频繁的页分裂。

  • 实际场景中,往往where和order by是没法都用到索引

  • 设计索引的时候,必须把经常用做范围查询的字段放在联合索引的最后一个,才能保证你SQL里每个字段都能基于索引去查询。

  • 在查询的时候如果有些字段是不使用的,可以用in (所有枚举值)的方式去写,这样可以让所有查询条件都用上你的索引,同时对范围查询的age字段必须放在最后一个,这样保证范围查询也能用上索引

  • 计算或者是函数不能使用索引

  • 可以将一个范围查询,去增加一个字段,让这个字段变成枚举查询;

    • where xx xxx and age>=xx and age<=xxx and latest_login_time>=xx(==原来==)
      • (province, city, sex, hobby, character, age, latest_login_time
    • 加一个does_login_in_latest_7_days,用户是否7天内登录的 字段
      • 索引改成(province, city, sex, hobby, character,does_login_in_latest_7_days, age)
      • 这个字段就是1,否则超过7天没登录,这个字段就是0
      • where xx xxx and age>=xx and does_login_in_latest_7_days=1 and age<=xxx(==现在==)
  • 针对一些低基数字段筛选(比如性别筛选)+评分排序(比如对分数排序)的查询场景,可以设计类似(sex, score)的辅助索引

==尽量利用一两个复杂的多字段联合索引,抗下你80%以上的 查询,然后用一两个辅助索引抗下剩余20%的非典型查询,保证你99%以上的查询都能充分利用索引,就能保证你的查询速度和性能!==


索引优化方案

  • 强制使用索引

force index(xxxxx索引名)

1
select * from t1 force index(index_category) where r1='xx' and r2='xx' order by id desc limit xx,xx
 请作者喝咖啡