MySQL索引添加的技巧

163 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 30 天,点击查看活动详情

索引

索引是数据库中一种用于提高查询效率的数据结构,它可以帮助数据库快速定位符合查询条件的数据,避免全表扫描等低效操作。在关系型数据库中,索引通常是建立在表的列上的,可以理解为是将表中的某些列按照一定的规则进行排序和组织,以便查询时能够快速定位到目标数据。

索引通常是按照 B-Tree 或哈希等数据结构进行组织的,其中 B-Tree 是最常用的一种索引类型。B-Tree 索引是一种多层树状结构,每个节点包含多个子节点和指向下一层节点的指针,每个叶子节点包含一个指向表中数据行的指针。通过不断地根据索引规则向下遍历索引树,可以快速定位到符合条件的数据行。

在建立索引时,需要根据实际情况选择适当的索引列和索引类型。一般来说,可以将经常用于查询、排序、分组等操作的列进行索引,但过多或不合理的索引可能会影响性能,甚至导致索引失效。因此,在设计和使用索引时,需要根据实际情况进行综合考虑,并进行测试和优化。

索引生效

索引在以下几种情况下会被查询优化器使用,提高查询效率:

  1. 等值查询:当查询语句中使用 WHERE 字句进行等值查询时,如果索引列和查询条件完全匹配,就可以利用索引进行查询优化。
  2. 范围查询:当查询语句中使用 WHERE 字句进行范围查询时,如果索引列和查询条件的左侧前缀匹配,就可以利用索引进行查询优化。
  3. 排序:当查询语句中使用 ORDER BY 字句进行排序时,如果排序的列是索引的一部分,就可以利用索引进行排序优化。
  4. 分组:当查询语句中使用 GROUP BY 字句进行分组时,如果分组的列是索引的一部分,就可以利用索引进行分组优化。
  5. 覆盖索引查询:如果查询的列都在索引中,就可以避免查询表数据,直接使用索引进行查询优化,这种情况也称为索引覆盖查询。

索引生效的原理是,数据库在执行查询语句时,会先根据查询条件从索引中定位到符合条件的数据行,然后再从表中读取对应的数据行,最后进行排序和分组等操作。由于索引通常是按照 B-Tree 或哈希等数据结构进行组织的,因此可以快速定位符合条件的数据行,从而提高查询效率。

需要注意的是,索引并不是越多越好,过多或不合理的索引可能会影响性能,甚至导致索引失效。因此,在设计和使用索引时,需要根据实际情况进行综合考虑,并进行测试和优化。

常见的索引技巧

在 MySQL 中添加索引可以提高查询效率,但过多或不合理的索引也可能会影响性能。下面是一些添加索引的技巧:

  1. 添加主键和唯一索引:主键和唯一索引可以确保表中每行数据的唯一性,因此应该优先添加。主键是一种特殊的唯一索引,用于唯一标识每行数据。
  2. 添加组合索引:组合索引可以覆盖多个列,可以提高查询效率,但也需要根据具体情况选择合适的列顺序和索引类型。
  3. 避免添加过多索引:过多的索引会降低数据的插入、更新和删除性能,并占用更多的磁盘空间,因此应该避免无用和重复的索引。
  4. 考虑查询中的字段类型和长度:索引的字段类型和长度应该与查询中的字段类型和长度保持一致,避免出现类型转换和截断。
  5. 对大表添加索引时应该分批次进行:对于大表,添加索引时应该分批次进行,以避免对系统性能产生影响。
  6. 避免使用前缀索引:前缀索引可以提高查询效率,但也容易出现数据冲突和误判,因此应该避免使用。

总之,在添加索引时应该根据实际情况进行综合考虑,并进行测试和优化,以达到最优的查询效率和性能。

索引失效

索引失效是指索引在查询过程中无法被使用,导致查询效率下降。以下是十几个可能导致索引失效的情况:

  1. 对索引列进行函数操作,例如将列进行计算、类型转换、字符串截断等操作。
  2. 对索引列进行运算,例如加、减、乘、除等操作。
  3. 在索引列上使用 NOT、<>、!= 等非等值查询条件。
  4. 使用了大量的 OR 条件,而且其中的列没有建立组合索引。
  5. 在索引列上使用 LIKE 模糊查询,例如 LIKE '%abc%'。
  6. 在索引列上使用字符串函数,例如 SUBSTR、LEFT、RIGHT、UPPER、LOWER 等函数。
  7. 在索引列上使用了 IS NULL 或 IS NOT NULL 条件。
  8. 在索引列上进行了类型转换,例如使用 CAST 或 CONVERT 函数。
  9. 索引列的数据类型不匹配,例如在字符串列上建立数值类型的索引。
  10. 索引列有 NULL 值,但查询语句中没有使用 IS NULL 条件。
  11. 使用了内置函数,例如 UUID()、NOW() 等,这些函数会使 MySQL 放弃使用索引。
  12. 在索引列上使用了 MySQL 不支持的函数或操作,例如自定义函数等。
  13. 对于枚举类型的列,在查询语句中使用字符串常量查询而不是使用枚举值查询。
  14. 查询条件中使用了反义词,例如 NOT、! 等。

需要注意的是,不同的数据库和版本可能对索引失效的情况有所不同,因此需要根据具体情况进行分析和优化。在实际应用中,可以通过 Explain 分析查询计划,找出索引失效的原因,并进行相应的调整和优化。

三星索引

  • 在WHERE条件中,找到所有等值谓词中的条件列,作为索引片中的开始列
  • 将GROUP BY和ORDER BY中的列加入到索引中
  • 将SELECT字段中剩余的列加入到索引

原理:最小化索引片、避免排序、避免回表直词

缺点:

  • 采用三星索引会让索引变宽,这样每个页(page)能够存储的索引数据新会变少从而增加了页加载的数量。
  • 虽然提升了单个SQL查询的效率,但是增加了索引维护的成本。