MST

星途 面试题库

面试题:MySQL索引扫描优化排序操作中的索引覆盖与回表问题

有一个`products`表,字段包括`product_id`、`product_name`、`category`、`price`、`description`。业务需求是查询`category`为'electronics'的产品,并按`price`降序排序。在优化此排序查询时,你发现创建`(category, price)`复合索引后,虽然排序性能有所提升,但仍存在一定的性能瓶颈。请深入分析可能存在的索引覆盖与回表问题对排序性能的影响,以及如何进一步优化索引设计来解决这些问题,同时给出新的索引创建和查询SQL语句。
45.8万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

索引覆盖与回表问题分析

  1. 索引覆盖:如果查询中所需的所有列都包含在索引中,那么数据库引擎可以直接从索引中获取数据,而无需回表操作。例如,若查询SELECT category, price FROM products WHERE category = 'electronics' ORDER BY price DESC;,创建(category, price)复合索引,此查询可以利用索引覆盖,性能较好。但如果查询为SELECT product_id, product_name, category, price, description FROM products WHERE category = 'electronics' ORDER BY price DESC;,由于product_idproduct_namedescription不在索引中,就需要回表操作。
  2. 回表影响排序性能:回表操作会增加I/O开销,因为需要从索引找到数据行的物理位置,再到数据页中获取完整的行数据。当大量数据需要回表时,会导致排序性能下降。在上述查询中,由于回表操作,即使有(category, price)索引,排序性能仍会受影响。

进一步优化索引设计

  1. 优化思路:为了减少回表操作,应尽量让查询所需的列都包含在索引中。对于上述查询,可以创建一个包含所有查询列的覆盖索引。
  2. 新索引创建SQL语句
CREATE INDEX idx_electronics_all ON products (category, price, product_id, product_name, description);
  1. 优化后的查询SQL语句
SELECT product_id, product_name, category, price, description 
FROM products 
WHERE category = 'electronics' 
ORDER BY price DESC;

这样,数据库引擎可以直接从索引中获取所有需要的数据,避免了回表操作,进一步提升排序查询的性能。