面试题答案
一键面试索引覆盖与回表问题分析
- 索引覆盖:如果查询中所需的所有列都包含在索引中,那么数据库引擎可以直接从索引中获取数据,而无需回表操作。例如,若查询
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_id
、product_name
、description
不在索引中,就需要回表操作。 - 回表影响排序性能:回表操作会增加I/O开销,因为需要从索引找到数据行的物理位置,再到数据页中获取完整的行数据。当大量数据需要回表时,会导致排序性能下降。在上述查询中,由于回表操作,即使有
(category, price)
索引,排序性能仍会受影响。
进一步优化索引设计
- 优化思路:为了减少回表操作,应尽量让查询所需的列都包含在索引中。对于上述查询,可以创建一个包含所有查询列的覆盖索引。
- 新索引创建SQL语句:
CREATE INDEX idx_electronics_all ON products (category, price, product_id, product_name, description);
- 优化后的查询SQL语句:
SELECT product_id, product_name, category, price, description
FROM products
WHERE category = 'electronics'
ORDER BY price DESC;
这样,数据库引擎可以直接从索引中获取所有需要的数据,避免了回表操作,进一步提升排序查询的性能。