大家好我是小耶写功课只是为了我踩过的坑你们别再踩了用EXPLAIN看执行计划大多数人只看三样东西type是不是ALL、key是不是NULL、Extra有没有Using filesort。但如果只看到这个程度你离“真正读懂执行计划”还有一段距离。真正该看的是rows和filtered的组合。单独看rows你只知道“要扫多少行”但不知道索引筛得干不干净。单独看filtered你只知道“过滤比例”但不知道绝对数量有多大。只有把两者放在一起看才能判断索引设计到底行不行。今天把rows和filtered的组合逻辑彻底拆开讲一遍。一、rows和filtered分别是什么rows优化器估算的、需要扫描的行数。它是一个相对值不是精确值但量级决定了查询成本的基数。filtered存储引擎返回的行中满足剩余WHERE条件的比例。比如rows1000、filtered10%表示存储引擎返回了1000行经过WHERE条件过滤后最终只留下100行。filtered100%表示索引精准定位无需额外过滤filtered越低说明索引筛掉的“垃圾”越少回表后还要过滤掉大量数据。关键认知rows是“扫描量”filtered是“过滤效率”。两者相乘rows × filtered%就是你最终需要返回的行数但更重要的是——filtered越低意味着索引帮上忙的就越少。二、三种典型组合及其诊断结论组合一rows小、filtered高✅ 索引设计优秀rows100filtered100%。优化器估算扫描100行全部命中不需要额外过滤。诊断结论索引精准定位了数据回表代价极小。说明索引列选择性和顺序都很好。组合二rows小、filtered低⚠️ 索引用了但没完全用rows100filtered10%。优化器估算扫描100行但最终只留下10行90%的行在回表后被过滤掉。诊断结论索引只帮你定位到了一小部分数据但WHERE条件中还有重要字段不在索引里导致回表后大量过滤。说明索引设计“缺了东西”——可以把被过滤的字段加进索引或调整索引列顺序。组合三rows大、filtered高⚠️ 索引命中精准但扫描范围太大rows100万filtered100%。优化器估算扫描100万行全部命中。诊断结论索引确实帮你精准定位了但问题在于——你要查的数据本身就有一百万行。这说明索引选择正确但查询条件本身过滤性太差比如查“2026年全年订单”或者数据量本身就大。这时候优化方向不是改索引而是考虑分区表、物化视图或业务层面缩小查询范围。组合四rows大、filtered低❌ 索引设计有问题最差组合rows100万filtered5%。扫描100万行最终只留5万行。诊断结论索引几乎没起什么作用——扫描了大量数据回表后又过滤掉95%。这是最需要优化的组合。大概率是索引列选择性极差比如status只有两三个值或者索引顺序完全不对。优先考虑重建索引或重新设计查询条件。三、真实案例从rows和filtered组合定位问题一个订单表有500万行数据status字段只有三个值PAID/UNPAID/REFUND索引为(status)。业务SQLsqlSELECT * FROM orders WHERE status PAID AND create_time 2026-01-01;EXPLAIN输出typekeyrowsfilteredExtrarefidx_status150万30%Using where诊断rows150万statusPAID占了约30%的数据filtered30%还要再过滤create_time。组合来看索引只筛掉了70%的数据回表后还要再过滤70%实际有效数据只有45万行。扫描150万行、回表150万次只为了拿45万行数据——浪费巨大。优化改成复合索引(status, create_time)。新EXPLAINtypekeyrowsfilteredExtrarefidx_status_ctime45万100%Using index condition效果rows从150万降到45万filtered从30%升到100%查询时间从4.2秒降到0.3秒。四、在多表JOIN中filtered决定了驱动顺序很多人不知道filtered在JOIN中还有一个关键作用——它直接影响优化器选择哪个表作为驱动表。优化器在选择JOIN顺序时会估算“驱动表行数 × filtered”作为被驱动表的匹配次数。比如表Arows10000filtered50% → 估算匹配5000次表Brows5000filtered90% → 估算匹配4500次优化器可能会选择表B作为驱动表即使它的rows更小——因为filtered更高意味着更少的无效匹配。这就是为什么有时候你加了个索引JOIN顺序突然变了——filtered变了优化器的估算变了。诊断建议如果你发现JOIN顺序不合理检查被驱动表的连接字段是否有索引以及filtered是否偏低。五、总结EXPLAIN的rows和filtered单独看都没什么用组合起来才是诊断索引设计质量的关键工具rowsfiltered诊断方向小高✅ 优秀保持小低⚠️ 索引缺字段加入被过滤的列大高⚠️ 数据量本身大分区/物化视图/缩小范围大低❌ 索引设计问题重建索引或改写SQL下次用EXPLAIN的时候别只看type和key。把rows和filtered两个数字摆在一起问问自己这个组合告诉我什么回答这个问题你就能从“会看EXPLAIN”升级到“会用EXPLAIN做诊断”。小耶在手SQL 不愁还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~