likes
comments
collection
share

深入探索MySQL:覆盖索引

作者站长头像
站长
· 阅读数 27

正文

原理

覆盖索引(Covering Index)是数据库索引的一个概念,指的是一个索引包含了查询所需的所有数据,因此查询操作可以直接通过索引来获取结果,而无需访问表中的数据行。使用覆盖索引可以显著提高查询性能,因为索引通常比数据行的存储更为紧凑,且在内存中的查找速度更快。在 SQL 查询中,如果一个 SELECT 语句所需的所有列都包含在一个索引中,那么这个索引就被称为覆盖索引。例如:

SELECT column1, column2 FROM table WHERE column1 = 'value';  

如果存在一个包含 column1 和 column2 的复合索引,那么这个索引就可以覆盖上述查询,数据库查询优化器(Query Optimizer)会利用这个索引来执行查询,而不需要再去数据表中查找对应的行。

使用覆盖索引的好处包括:

1. 减少磁盘I/O:由于数据可以直接从索引中读取,减少了对数据表的访问,因此可以减少磁盘I/O操作。 2. 加快查询速度:索引结构(如B-Tree)使得数据检索效率高,尤其是当索引已经被加载到内存中时。 3. 降低CPU消耗:减少了数据查找和排序的计算量。 4. 减少锁竞争:在InnoDB存储引擎中,如果一个查询可以通过覆盖索引来完成,则可能减少对表的行锁定,从而减少锁竞争。 5.节省内存空间:如果查询可以仅通过索引来完成,那么MySQL查询优化器可能不需要为查询创建一个大的内存临时表。  由于InnoDB的聚簇索引的特点, 覆盖索引对InnoDB表特别有用。 InnoDB的二级索 引在叶子节点中保存了记录的主键值, 所以如果二级索引能够覆盖查询, 则可以避 免对主键索引的二次查询

在设计数据库和索引时,考虑到覆盖索引的优势,开发者和数据库管理员会尝试通过创建合适的索引来优化查询性能。然而,也需要权衡,因为过多的索引会增加维护成本,包括更新、插入和删除操作时的额外开销。

-- 找到未使用索引的最好办法就是使用系统数据库 performance_schema和sys。 在sys数据库中, 在table_io_waits_summary_by_index_usage视 图中可以非常简单地知道哪些索引从来没有被使用过:

SELECT * from sys.schema_unused_indexes

或者使用下面语句也

SELECT object_schema AS database_name,
       object_name AS table_name,
       index_name
FROM performance_schema.table_io_waits_summary_by_index_usage
WHERE index_name IS NOT NULL
  AND count_star = 0 
ORDER BY object_schema, object_name, index_name;

何时使用覆盖索引?

覆盖索引最适合于以下场景:

  • 查询只需要表的一部分列,并且这些列都包含在索引中。
  • 表的数据行很大,而索引项则相对较小。
  • 表中的数据行分布在磁盘的不同位置,而索引则更有可能在内存中或物理上更接近。

注意事项

  • 覆盖索引不是万能的,对于需要���问表中大部分或全部列的查询,覆盖索引可能不会带来性能提升。
  • 索引列的顺序很重要,应根据查询条件和选择性来设计索引。
  • 过度使用覆盖索引可能会导致索引膨胀,因为每个额外的索引都需要存储空间和维护开销。
  • 当表结构发生变化时,可能需要重新评估和调整索引策略。

总结

覆盖索引是MySQL中一种高效的查询优化方法,它指的是一个索引包含了查询中所需的所有字段,使得数据库可以直接从索引中获取数据,而无需访问数据行。这种技术可以显著减少磁盘I/O操作,提高查询速度,尤其在处理大表和复杂查询时效果显著。要实现覆盖索引,需要在创建索引时包括所有查询所需的列。使用EXPLAIN语句可以帮助确定查询是否利用了覆盖索引。合理使用覆盖索引可以优化查询性能,但也要注意避免索引过多导致的维护成本和存储开销。

转载自:https://juejin.cn/post/7400231126797434931
评论
请登录