索引下推(Index Condition Pushdown, ICP)
索引下推是MySQL 5.6及以上版本引入的一种优化技术。
简单来说,它允许存储引擎在使用索引进行数据检索时,将原本需要在服务器层(如MySQL的SQL层)进行的筛选条件下推到存储引擎层。
这样,存储引擎在遍历索引时就能提前对索引中的数据进行过滤,减少不必要的数据返回给服务器层,从而提高查询效率。
示例
假设有一个名为employees的表,包含employee_id(主键)、name、age和department字段,并且在name和age字段上建立了联合索引(idx_name_age)。
执行如下查询:
SELECT * FROM employees WHERE name LIKE '%张%' AND age > 30;
在没有索引下推的情况下,存储引擎会根据联合索引idx_name_age找到所有name包含“张”字的记录,然后将这些记录返回给服务器层。
服务器层再对返回的记录进行age > 30这个条件的筛选。这可能会导致大量不必要的数据传输,因为存储引擎返回的记录中可能有很多不符合age > 30这个条件。
而在有索引下推的情况下,存储引擎在遍历联合索引idx_name_age时,会同时考虑age > 30这个条件。
只有那些既满足name LIKE '%张%'又满足age > 30的记录才会被返回给服务器层。这样就减少了存储引擎返回给服务器层的数据量,提高了查询效率。
索引覆盖(Covering Index)
索引覆盖则是一种查询性能优化的技术。
它指的是查询所需的所有列的数据都能够从索引中获取,而无需访问表中的数据行。换句话说,当查询语句中涉及的所有列都包含在索引中时,数据库就可以直接通过索引返回结果,而无需进行额外的数据查找。
示例
假设有一张表users,如下:
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(100),
age INT
);
如果有一个查询语句:
SELECT name, email FROM users WHERE name = 'John';
并且我们在name和email字段上创建了一个组合索引:
CREATE INDEX idx_name_email ON users(name, email);
由于查询只涉及name和email两个字段,并且这两个字段已经包含在索引idx_name_email中,因此数据库可以直接从索引中获取结果,而无需访问表的数据行。
这就是一个典型的索引覆盖的例子。
回表(Index Lookups)
回表是一个在数据库查询过程中经常出现的操作,尤其是在使用非聚簇索引进行查询时。
非聚簇索引只包含索引列的数据,而不包含其他列的数据。因此,当查询语句需要返回非索引列的值时,数据库就需要回到原始数据所在的内存页进行读取,这个过程就是回表。
回表操作会增加查询的成本,因为它需要更多的磁盘和内存访问来获取行的其他列数据。
特别是在大规模数据表上或高并发的查询场景下,回表操作可能会成为性能瓶颈。
示例
假设我们有一个包含姓名和年龄的表,并在姓名字段上创建了非聚簇索引。
当执行如下查询时:
SELECT * FROM users WHERE name = '张三';
由于查询需要返回所有列的数据,而姓名字段上的索引只包含姓名和对应的主键值,并不包含年龄等其他信息。
因此,数据库在通过索引定位到满足条件的记录后,还需要回到主键索引上,根据主键值再次查询以获取完整的数据行。这个过程就是回表。
总结
• 索引下推:通过提前在索引层应用过滤条件,减少不必要的数据返回给服务器层,从而提高查询效率。 • 索引覆盖:通过确保查询所需的所有列都包含在索引中,避免回表操作,直接通过索引返回结果。 • 回表:在使用非聚簇索引进行查询时,由于索引不包含所有列的数据,需要回到原始数据所在的内存页进行读取的过程。
这三种技术都是数据库优化中非常重要的手段,合理应用它们可以显著提升查询性能。
你诺喜欢,请点个关注哦
大家可以发送消息:202501
领取计算机黑皮书191本(1月有效)
推荐文章: