1.索引个数限制
1) 索引是双刃剑,会增加维护负担,增大IO压力,索引占用空间是成倍增加的
2) 单张表的索引数量控制在5个以内,或不超过表字段个数的20%。若单张表多个字段在查询需求上都要单独用到索引,需要经 过DBA评估。
2.避免冗余索引
1) InnoDB表是一棵索引组织表,主键是和数据放在一起的聚集索引,普通索引最终指向的是主键地址,所以把主键做最后一列 是多余的。如f_crm_id作为主键,联合索引(f_user_id,f_crm_id)上的f_crm_id就完全多余
2) (a,b,c)、(a,b),后者为冗余索引。可以利用前缀索引来达到加速目的,减轻维护负担
3.没有特殊要求,使用自增id作为主键
1) 主键是一种聚集索引,顺序写入。组合唯一索引作为主键的话,是随机写入,适合写少读多的表
2) 主键不允许更新
4.索引尽量建在选择性高的列上
1) 不在低基数列上建立索引,例如性别、类型。但有一种情况,idx_feedbackid_type (f_feedback_id,f_type),如果经常 用 f_type=1 比较,而且能过滤掉90%行,那这个组合索引就值得创建。有时候同样的查询语句,由于条件取值不同导致使 用不同的索引,也是这个道理。
2) 索引选择性计算方法(基数 ÷ 数据行数)
Selectivity = Cardinality / Total Rows = select count(distinct col1)/count(*) from tbname,越接近1说明col1上使用索 引的过滤效果越好
3) 走索引扫描行数超过30%时,改全表扫描
5.最左前缀原则
1) mysql使用联合索引时,从左向右匹配,遇到断开或者范围查询时,无法用到后续的索引列比如索引idx_c1_c2_c3 (c1,c2,c3),相当于创建了(c1)、(c1,c2)、(c1,c2,c3)三个索引,where条件包含上面三种情况的字段比较则可以用到索引, 但像 where c1=a and c3=c 只能用到c1列的索引,像 c2=b and c3=c等情况就完全用不到这个索引
2) 遇到范围查询(>、<、between、like)也会停止索引匹配,比如 c1=a and c2 > 2 and c3=c,只有c1,c2列上的比较能用到 索引,(c1,c2,c3)排列的索引才可能会都用上
3) where条件里面字段的顺序与索引顺序无关,mysql优化器会自动调整顺序
6.前缀索引
1) 对超过30个字符长度的列创建索引时,考虑使用前缀索引,如 idx_cs_guid2 (f_cs_guid(26))表示截取前26个字符做索 引,既可以提高查找效率,也可以节省空间
2) 前缀索引也有它的缺点是,如果在该列上 ORDER BY 或 GROUP BY 时无法使用索引,也不能把它们用作覆盖索 引(Covering Index)
3) 如果在varbinary或blob这种以二进制存储的列上建立前缀索引,要考虑字符集,括号里表示的是字节数
7.合理使用覆盖索引
1) INNODB存储引擎中,secondary index(非主键索引,又称为辅助索引、二级索引)没有直接存储行地址,而是存储主键值。
2) 如果用户需要查询secondary index中所不包含的数据列,则需要先通过secondary index查找到主键值,然后再通过主键 查询到其他数据列,因此需要查询两次。覆盖索引则可以在一个索引中获取所有需要的数据列,从而避免回表进行二次查 找,节省IO因此效率较高。
8.最左前缀原则
1) 如不在定义了 ON UPDATE CURRENT_STAMP 的列上创建索引,维护成本太高(好在mysql有insert buffer,会合并索 引的插入)