EXPLAIN进阶:读懂key_len和filtered

发布时间:2026/6/2 14:08:26

EXPLAIN进阶:读懂key_len和filtered ​关键词​EXPLAINkey_lenfiltered执行计划联合索引SQL优化大家好我是小耶写功课只是为了我踩过的坑你们别再踩了做SQL优化就像体检。你拿到一份体检报告EXPLAIN的输出大部分人只盯着“红细胞”type列和“白细胞”Extra列有没有超标却忽略了“关键蛋白”key_len和“炎症因子”filtered。这两个指标恰好能告诉你联合索引到底用了几列索引用得有多好key_len和filtered是什么用快递分拣系统来类比​key_len​相当于你扫描条形码的长度。条形码越长包含的信息越多比如省、市、区、街道、门牌号。key_len越大说明联合索引中实际使用的列越多查询定位越精准。​filtered​相当于分拣员根据条形码初步分拣后剩下的包裹中还需要人工二次分拣的比例。filtered越高越接近100%说明索引定位已经很准确不需要额外过滤filtered越低说明索引只帮你筛掉了一小部分还要花大量时间在回表后过滤剩下的数据。一、key_len的计算方法MySQL中各数据类型的字节长度如下表数据类型字节长度备注TINYINT1SMALLINT2INT4BIGINT8DATE3TIMESTAMP4DATETIME5MySQL 5.6CHAR(n)n × 字符集字节数utf8mb4为4字节/字符VARCHAR(n)n × 字符集字节数 1~2长度标识允许NULL额外1示例计算假设联合索引(a, b, c)aINT NOT NULL → 4字节bINT允许NULL → 4 1 5字节cVARCHAR(10) utf8mb4 NOT NULL → 10×4 2 42字节使用列key_len只用a4ab459abc454251实战案例sqlCREATE TABLE user_log ( id INT PRIMARY KEY, user_id INT NOT NULL, log_date DATE NOT NULL, log_type TINYINT NOT NULL, msg VARCHAR(255), INDEX idx_union (user_id, log_date, log_type) );查询条件key_len说明user_id 10086 AND log_date 2026-06-01437用到前两列user_id 10086 AND log_type 14跳过了log_date只能用到第一列最左前缀原则二、filtered的解读filtered表示存储引擎返回的行中满足剩余WHERE条件的比例估算值。filtered值含义100%索引精准定位无需额外过滤30%索引定位后还要过滤掉70%的行回表开销大5%索引选择性很差几乎没用​在单表查询中​filtered帮助判断索引设计是否合理。如果联合索引全用到但filtered仍然很低说明索引列的选择性差比如status只有几个值。​在多表JOIN中​优化器会估算“驱动表行数 × filtered”作为被驱动表的匹配次数。filtered低可能导致优化器选择错误的驱动顺序。三、key_len filtered 组合分析矩阵key_lenfiltered诊断优化建议大多列高90%索引设计优秀无需调整小单列中低查询条件未覆盖索引前列调整联合索引列顺序或改写SQL大多列低索引列选择性差换用更高选择性的列或使用覆盖索引小单列高单列索引选择性好可考虑扩展为联合索引避免回表四、真实优化案例原SQLsqlSELECT * FROM orders WHERE create_time 2026-05-01 AND status PAID;原索引(create_time, status)EXPLAIN结果typerangekey_len5create_time为DATEfiltered10%。分析只用了create_time索引status过滤在回表后执行。filtered10%意味着扫描行中90%被过滤掉回表开销大。优化方案将索引顺序改为(status, create_time)。因为status选择性虽然不高但作为前导列可以快速定位到PAID行再通过create_time范围扫描。优化后key_len status create_timefiltered提升到100%查询时间从3秒降到0.2秒。五、注意事项​key_len不是越大越好​如果用了低选择性列反而可能扫描更多行。​filtered是估算值​依赖统计信息。如果统计信息过旧执行ANALYZE TABLE更新。​版本限制​MySQL 5.6及以下版本没有filtered列。​JOIN中的重要性​驱动表的filtered值直接影响被驱动表的访问次数。六、价值总结学会解读key_len和filtered你就能从“大概知道用了索引”升级到“精确知道索引怎么用的、哪里需要优化”。配合ANALYZE TABLE更新统计信息让优化器做出更准确的决策是DBA走向高级优化的必经之路。小耶在手SQL 不愁还有什么想了解的欢迎留言小耶一定知无不言言无不尽……我们下次见~参考文献MySQL官方文档《EXPLAIN Output Format》《高性能MySQL》第4版第9章查询优化

相关新闻