您的位置:首页 > 文旅 > 旅游 > 厦门网站建设公司排行榜_项目如何进行网络推广_老域名购买_泰安网络推广培训

厦门网站建设公司排行榜_项目如何进行网络推广_老域名购买_泰安网络推广培训

2025/2/6 22:36:50 来源:https://blog.csdn.net/yang2330648064/article/details/145099067  浏览:    关键词:厦门网站建设公司排行榜_项目如何进行网络推广_老域名购买_泰安网络推广培训
厦门网站建设公司排行榜_项目如何进行网络推广_老域名购买_泰安网络推广培训

文章目录

  • 说明
  • MySQL索引覆盖(覆盖索引, Covering Index)
    • 覆盖索引的概念
    • 覆盖索引的示例
    • 示例查询及索引覆盖情况
    • 覆盖索引的性能优势
    • 覆盖索引的实现条件
    • 覆盖索引 vs 非覆盖索引
    • 覆盖索引的限制
    • 如何设计覆盖索引
    • 覆盖索引的实际案例
      • 场景 1:电商系统中的订单查询
      • 场景 2:博客系统中的文章搜索
    • 总结

说明

  • 本文章内容由chatGpt4对话内容整理而来,如有错误之处,请在评论区留言!

MySQL索引覆盖(覆盖索引, Covering Index)

  • 索引覆盖 是指查询所需的所有列的数据都可以通过索引直接获取,而无需访问表中的实际数据行(即无需回表)。
  • 当查询满足索引覆盖的条件时,MySQL 可以只通过读取索引完成查询操作,从而显著提高查询性能。

覆盖索引的概念

  • 索引覆盖是指查询所涉及的字段(SELECT 的字段以及 WHERE、GROUP BY、ORDER BY 的字段)都被索引包含。如果查询中的所有字段都能从索引中获取,那么 MySQL 就可以直接在索引中返回结果,而不需要访问数据行。
  • 索引通常存储在一个更加紧凑的结构中,数据量较小,访问效率更高。避免了 “回表” 的开销(回表是指通过主键从聚簇索引或数据页中获取数据)。

覆盖索引的示例

假设有一个表 users

CREATE TABLE users (id INT PRIMARY KEY,         -- 主键name VARCHAR(50),           -- 用户名email VARCHAR(50),          -- 邮箱age INT,                    -- 年龄INDEX idx_name_email (name, email) -- 联合索引
);

示例查询及索引覆盖情况

  1. 索引覆盖的情况
    SELECT name, email FROM users WHERE name = 'Alice';
    
    • 索引 idx_name_email 包含 nameemail,查询的字段完全被索引覆盖。
    • MySQL 可以直接从索引中返回结果,无需访问实际表数据。
  2. 索引不覆盖的情况
    SELECT name, email, age FROM users WHERE name = 'Alice';
    
    • 索引 idx_name_email 包含了 nameemail,但不包含 age
    • 查询时,MySQL 会从索引中找到符合 name = 'Alice' 的记录,然后通过主键回表查找 age 字段。
  3. 索引部分使用的情况
    SELECT email FROM users WHERE name = 'Alice';
    
    • 查询使用索引 idx_name_emailname 列作为过滤条件,并获取email 列。这依然属于索引覆盖查询,因为所需的字段都在索引中。

覆盖索引的性能优势

  1. 减少 I/O 操作:索引通常比表数据小得多,且索引存储是紧凑的树形结构(例如 B+ 树),查询效率更高。如果可以直接从索引中获取数据,就不需要回表,大大减少磁盘 I/O。
  2. 提高查询速度:查询只在索引层完成,无需访问表的实际数据行。避免了读取大量不必要的表数据。
  3. 降低锁定范围:如果查询在索引中即可完成,可以减少对数据行的访问,从而降低行锁或表锁的影响。

覆盖索引的实现条件

  1. 必须有适当的索引
    • 覆盖索引依赖于索引的列包含了查询所需的所有字段。
    • 可以是单列索引,也可以是多列的联合索引。
  2. 选择性字段的优先设计
    • 查询中频繁用到的过滤条件(WHERE)或查询字段(SELECT)应优先设计为索引。
  3. InnoDB 表中的聚簇索引
    • InnoDB 存储引擎的主键索引是聚簇索引(clustered index),主键包含了实际行数据。
    • 如果查询字段只涉及主键索引,天然满足覆盖索引的条件。

覆盖索引 vs 非覆盖索引

特性覆盖索引非覆盖索引
是否回表无需回表,所有数据直接从索引中获取需要回表,从索引获取主键后再查找表数据
查询效率高,减少 I/O 操作较低,增加 I/O 操作
索引列要求查询字段必须全部在索引中查询字段不要求全部在索引中
常见场景多用于 SELECT 查询查询字段较多或数据更新频繁时更常见

覆盖索引的限制

  1. 查询字段必须包含在索引中:如果查询字段超出索引的覆盖范围,MySQL 必须回表获取缺失的数据。
  2. 索引过多会影响写性能:为了覆盖索引而创建大量的索引,可能会降低数据的写入速度,因为每次写操作都需要维护多个索引。
  3. 不支持全字段匹配模糊查询:如果查询条件涉及 LIKE '%xxx' 或非前缀模糊匹配的字段,覆盖索引无法发挥作用。
  4. 大字段类型的限制:索引中不适合存储大字段(如 TEXT、BLOB),这些字段通常不会被用于覆盖索引。

如何设计覆盖索引

  1. 常用查询字段优先索引
    • 优先为 WHERE、ORDER BY 和 SELECT 中频繁出现的字段建立索引。
    • 如果查询字段较少,可以通过适当调整索引覆盖范围来满足覆盖索引的条件。
  2. 联合索引优化:联合索引(多列索引)设计时,要注意字段顺序,优先将过滤条件的列放在前面。
  3. 避免过度索引:虽然覆盖索引可以提升查询性能,但索引维护的开销也需要考虑,过多的索引可能导致写性能下降。

覆盖索引的实际案例

场景 1:电商系统中的订单查询

表结构:

CREATE TABLE orders (order_id INT PRIMARY KEY,user_id INT NOT NULL,order_date DATE NOT NULL,total_amount DECIMAL(10, 2) NOT NULL,INDEX idx_user_date_amount (user_id, order_date, total_amount)
);

查询:

SELECT user_id, order_date, total_amount
FROM orders
WHERE user_id = 123 AND order_date >= '2023-01-01';

优化:

  • 索引 idx_user_date_amount 覆盖了所有查询字段。
  • 查询可直接从索引中返回结果,无需回表。

场景 2:博客系统中的文章搜索

表结构:

CREATE TABLE posts (post_id INT PRIMARY KEY,title VARCHAR(255),content TEXT,author_id INT,created_at DATETIME,INDEX idx_author_created (author_id, created_at)
);

查询:

SELECT author_id, created_at
FROM posts
WHERE author_id = 1 AND created_at > '2023-01-01';

优化:

  • 索引 idx_author_created 包含 author_idcreated_at
  • 查询字段被索引完全覆盖,可以通过覆盖索引加速查询。

总结

  • 覆盖索引 是 MySQL 中的一种性能优化技术,当查询所需的字段完全被索引覆盖时,MySQL 可以直接通过索引返回结果,避免回表操作。
  • 它的主要优势是 减少 I/O、提高查询速度,尤其适用于读操作较多的场景。
  • 设计覆盖索引时应结合实际查询需求,合理选择索引列,同时避免过多索引对写性能造成负面影响。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com