MySQL关联查询中TAREA_EMPRESA_表未使用索引问题求助
为什么TAREA_EMPRESA_表明明有主键索引却走全表扫描?
我来帮你拆解这个问题——其实这种情况在小数据集的表上非常常见,MySQL优化器的选择看似反直觉,但本质是基于成本计算的合理决策。
核心原因:小表的全表扫描成本更低
从你提供的TAREA_EMPRESA_表数据来看,它只有4行记录。MySQL的查询优化器会对比两种执行路径的开销:
- 走主键索引:需要先遍历索引树定位到匹配的主键值,再回表读取对应的行数据,这涉及到索引页和数据页的IO操作。
- 全表扫描(type=ALL):直接读取表中所有4行数据,然后过滤出匹配关联条件的行。
对于只有4行的表,全表扫描的IO开销和CPU开销都远低于走索引的开销——毕竟读取4行数据几乎瞬间完成,没必要额外走索引树的流程。优化器经过成本计算后,自然会选择全表扫描。
验证这个结论的方法
你可以通过FORCE INDEX强制MySQL使用主键索引,看看执行计划的变化:
EXPLAIN SELECT TE.PK_ID_TAREA_EMPRESA AS ID_EMPRESA, TE.NOMBRE AS NOMBRE_EMPRESA, TCA.PK_ID_TAREA_CATEGORIA AS ID_CATEGORIA, TCA.NOMBRE AS NOMBRE_CATEGORIA, T.TIPO AS TIPO, T.CLIENTE AS CLIENTE, T.PETICION AS PETICION, T.FACTURABLE AS FACTURABLE, TCOM.COMENTARIO AS COMENTARIO, TCOM.PENDIENTE AS PENDIENTE FROM TAREA_COMENTARIO TCOM INNER JOIN TAREA T ON TCOM.TAREA_TIPO = T.TIPO AND TCOM.TAREA_CLIENTE = T.CLIENTE AND TCOM.TAREA_PETICION = T.PETICION INNER JOIN TAREA_EMPRESA_ TE FORCE INDEX (PRIMARY) ON TCOM.FK_ID_TAREA_EMPRESA = TE.PK_ID_TAREA_EMPRESA INNER JOIN TAREA_CATEGORIA_ TCA ON TCOM.FK_ID_TAREA_CATEGORIA = TCA.PK_ID_TAREA_CATEGORIA INNER JOIN TAREA_CLASIFICACION_ TCL ON TCOM.FK_ID_TAREA_CLASIFICACION = TCL.PK_ID_TAREA_CLASIFICACION WHERE TCOM.FK_ID_TAREA_CLASIFICACION = 70 GROUP BY TCOM.FK_ID_TAREA_EMPRESA, TCOM.FK_ID_TAREA_CATEGORIA, TCOM.FK_ID_TAREA_CLASIFICACION, TCOM.TAREA_TIPO, TCOM.TAREA_CLIENTE, TCOM.TAREA_PETICION;
执行这条语句后,你会看到TE表的type变成eq_ref,key字段显示为PRIMARY——这证明索引是可用的,只是优化器主动选择了更高效的全表扫描。
额外说明
如果未来TAREA_EMPRESA_表的数据量大幅增长(比如达到几百上千行),MySQL优化器会自动调整执行计划,优先选择走主键索引,不需要你手动干预。当前的全表扫描完全是正常且高效的行为,不需要担心性能问题。
内容的提问来源于stack exchange,提问作者Christian Téllez Giraldo
相关产品推荐
相关产品推荐

