filtered 表示能过滤多少数据
- 和复合索引/联合索引有关
- 和走索引时的WHERE查询条件有关
在 MySQL 的 EXPLAIN 执行计划中,filtered 列表示存储引擎返回的数据在服务器层过滤后剩余的比例 (百分比)。它的值范围是 0% 到 100%,具体含义如下:
filtered = 100 的含义
100%表示没有额外的过滤- 存储引擎返回的所有行都完全符合查询条件,服务器层不需要额外过滤。
- 通常出现在以下情况:
- 查询条件中的列全部被索引覆盖(即使用了覆盖索引)。
- 没有
WHERE条件,或者WHERE条件仅通过索引就能完全匹配。
- 与
type和key的关系- 如果
type是ref、eq_ref、range等高效访问类型,且key使用了正确的索引,filtered通常会接近100%。 - 如果
type是ALL(全表扫描)或index(全索引扫描),filtered可能较低(例如10%),表示存储引擎返回了大量数据,但服务器层只保留了一小部分。
- 如果
你的执行计划分析
在你的 EXPLAIN 结果中:
filtered = 100type = ref(使用索引等值查找)key = idx_purchaser_id_related_order_sn(实际使用的索引)
这表明:
- 存储引擎通过索引
idx_purchaser_id_related_order_sn快速定位到符合条件的行。 - 返回的所有行(预估
rows=2)完全满足查询条件,服务器层无需过滤。 - 这是一个高效的查询 ,因为:
- 使用了正确的索引(
ref访问类型)。 - 没有冗余的数据读取或过滤。
- 使用了正确的索引(
对比示例:filtered < 100 的情况
如果查询是:
sql
`SELECT * FROM order_info_14 WHERE purchaser_id = 123 AND order_status = 'completed';`
但 order_status 不在索引中,执行计划可能是:
`type: ref, key: idx_purchaser_id_related_order_sn, filtered: 10%`
filtered=10%表示:- 存储引擎通过
idx_purchaser_id_related_order_sn返回了 100 行(rows=100)。 - 但只有 10 行(10%)满足
order_status = 'completed',其余 90 行被服务器层过滤掉。
- 存储引擎通过
如何利用 filtered 优化查询?
- 追求
filtered=100- 确保
WHERE条件中的列被索引覆盖(尤其是选择性高的列)。 - 使用覆盖索引(
Extra: Using index)避免回表。
- 确保
- 警惕低
filtered值- 如果
filtered很低(如1%),说明存储引擎返回了大量无用数据,可能导致性能问题。 - 优化方法:
- 添加复合索引(包含
WHERE中的所有条件列)。 - 重写查询以减少数据扫描范围。
- 添加复合索引(包含
- 如果
总结
filtered=100是好事,表示查询高效,没有冗余数据读取。- 如果
filtered较低,需检查索引是否充分覆盖查询条件,或考虑优化查询逻辑。 - 结合
type、key、rows等列综合分析执行计划。