标准答案
- 先根据 WHERE、JOIN、ORDER BY 和 SELECT 的实际组合确定索引列,而不是只看单个过滤字段。
- 索引包含查询所需的全部列时,优化器可以直接从二级索引返回结果,减少主键回表。
- 覆盖索引最适合返回字段稳定且较少的读热点,例如按用户和状态读取最近的订单 ID 与创建时间。
- 新增索引列会增加索引宽度、写放大和缓存压力,应只覆盖高价值查询。
- 是否真正覆盖要通过执行计划确认,避免 SELECT * 破坏原本的覆盖条件。
题目解析
覆盖索引的收益常来自减少大量随机读取,而不是让一次单行查询少一个步骤。分页列表、批处理扫描和报表预过滤如果每行都回表,累计成本会远大于 SQL 文本表面看起来的差异。
它不是万能优化。若查询本来只返回很少行,或者新增字段让索引远比数据页还宽,收益可能不值得。应基于慢查询、QPS、返回行数和写入负担做判断。
常见误区
- 把 SELECT * 用在高频列表查询,迫使数据库回表读取并不展示的大字段。
- 不验证执行计划就假设联合索引能够覆盖所有查询。