索引优化

Exisi 2023-04-14 23:14:30
Categories: Tags:
  1. 索引值
    • 只要列中包含有NULL值都将不会被包含在索引中,多列索引中只要有一列含有 NULL 值,那么这一列对于此多列索引就是无效的。所以我们在数据库设计时,应该为字段设置 NOT NULL 约束,或着设置非 NULL 的默认值。

 

  • 字符类型务必加上引号,若varchar类型字段值不加单引号,可能会发生数据类型隐式转化,自动转换为int型,使索引无效。

 

  • 不在索引字段上进行计算、函数、类型转换(自动\手动),防止导致索引失效,执行全表扫描

 

  1. 定义
    • 尽量的扩展索引,非必要不新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

 

  • 建联合索引的时候,区分度最高的字段在最左边。

 

  • 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。虽然唯一索引会影响insert速度,但是对于查询的速度提升是非常明显的。另外,即使在应用层做了非常完善的校验控制,只要没有唯一索引,在并发的情况下,依然有脏数据产生。

 

  1. 区分度
    • 更新频繁的字段上不建立索引。因为更新操作会变更B+树,重建索引,这个过程是十分消耗数据库性能的。

 

  • 区分度不大的字段上不宜建立索引。类似于性别这种区分度不大的字段,建立索引的意义不大。因为不能有效过滤数据,性能和全表扫描相当。

 

  • 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0

 

  • 尽可能使用短索引。如果对字符串列进行索引,应该指定一个前缀索引。较小的索引涉及的磁盘 IO 较少,较短的值比较起来更快。更为重要的是,对于较短的键值,索引高速缓存中的块能容纳更多的键值,因此,MySQL 也可以在内存中容纳更多的值。这样就增加了找到行而不用读取索引中较多块的可能性。

 

  1. 查询条件
    • 模糊查询(Like)查询,左侧尽量不要加%

 

  • 负向条件查询不能使用索引(!=<>not innot existsnot like等),可以优化为in查询,但是前提是区分度要高,返回数据的比例在30%以内

 

  • 尽量将范围查询字段放在最后(放在最后联合索引使用最充分,放在中间联合索引使用不充分)。使用联合索引时范围列(当前范围列索引生效)后面的索引列无法生效,同时索引最多用于一个范围列,如果查询条件中有多个范围列,也只能用到一个范围列索引。

 

  • OR左右查询字段只有一个是索引,会使该索引失效,只有当OR左右查询字段均为索引列时,这些索引才会生效。索引改为使用 唯一索引(UNION)效率高。

 

  • 查询记录的时候,不要使用 SELECT * FROM,只取需要的数据,尽量只利用索引覆盖,可以减少回表操作,提升效率

 

  • 单表查询时,保证 WHERE 查询条件的顺序和个数与索引建立的顺序和个数要保持一致

 

  • 遵循最左匹配原则,即where的查询条件尽量要从索引的列的最左列开始并且不跳过索引中的列

 

  • 多表关联查询时,保证被关联的字段需要有索引

  • 当全表扫描速度比索引速度快时,MySQL会使用全表扫描,此时索引失效。

 

  • 如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果

 

 

来自 <https://blog.51cto.com/zhongmayisheng/4959191>