mysql中的全表扫描与索引优化技巧

EXPLAIN显示type=ALL表示全表扫描,响应慢,主因是缺索引、函数操作或隐式转换;应结合rows和filtered评估、按最左前缀建联合索引、优先等值条件、善用覆盖索引并定期更新统计信息。

mysql中的全表扫描与索引优化技巧

为什么 EXPLAIN 显示 type=ALL 就该警惕

这表示 MySQL 正在执行全表扫描,即逐行读取整张表来匹配条件。哪怕只有几万行,一旦并发上来或字段含大文本,响应就会明显变慢。常见诱因是 WHERE 条件列没索引、用了函数(如 WHERE YEAR(created_at) = 2023)、或隐式类型转换(比如对字符串字段传数字值)。

  • EXPLAIN FORMAT=TREE 查看更直观的执行路径,注意 rowsfiltered 的乘积是否远超实际返回行数
  • 避免在索引列上使用 !=NOT INLIKE '%abc' —— 这些基本无法走索引
  • 联合索引要注意最左前缀:如果建了 (a, b, c),那 WHERE b = ?WHERE c = ? 是不会命中索引的

如何判断该加单列索引还是联合索引

单列索引适合高频独立查询的字段,比如 user_idstatus;联合索引则要按「查询频率高 + 过滤性强 + 出现在 WHERE 最左侧」的顺序排列。MySQL 8.0+ 支持降序索引,但 ORDER BY a ASC, b DESC 需显式声明 (a ASC, b DESC) 才能完全覆盖排序。

  • 优先把等值条件列放前面,范围查询(>, BETWEEN)放后面,ORDER BY 列尽量接在最后
  • 例如查询 SELECT * FROM orders WHERE shop_id = ? AND status = ? ORDER BY created_at DESC,推荐索引为 (shop_id, status, created_at)
  • 别盲目给所有 WHERE 字段都建索引——索引越多,写入越慢,且优化器可能选错执行计划

SELECT * 和覆盖索引的关系

如果一个查询的所有字段都能从索引中直接获取(即「覆盖索引」),MySQL 就不必回表查聚簇索引,性能提升显著。但前提是这些字段必须全部出现在同一个索引的「叶子节点」里。

网奇企业网站管理系统CWMS2.0 英文版

网奇企业网站管理系统CWMS2.0 英文版

CWMS 2.0功能介绍:一、 员工考勤系统,国内首创CWMS2.0的企业员工在线考勤系统。二、 自定义URL Rewrite重写,友好的搜索引擎 URL优化。三、 代码与模板分离技术,支持超过5种类型的模板类型。包括:文章、图文、产品、单页、留言板。四、 购物车功能,CWMS2.0集成国内主流支付接口。如:淘宝、易趣、快钱等。完全可媲美专业网上商城系统。五、 多语言自动切换 中英文的说明。六、

下载

  • 例如有索引 (user_id, email, created_at),那么 SELECT user_id, email FROM users WHERE user_id = ? 就是覆盖索引查询
  • SELECT * 几乎不可能被覆盖,因为主键以外的字段(尤其是 TEXTBLOB)不会存进二级索引
  • EXPLAINExtra 列是否含 Using index,有就是覆盖了;若出现 Using index condition,说明用了 ICP(索引条件下推),也比全表扫描强

哪些场景下索引会失效或被忽略

即使建了索引,MySQL 也可能不走它。典型情况包括:统计信息过期、索引选择性太低(比如 gender 只有 ‘M’/’F’)、查询返回大量行(优化器认为全表扫描反而更快)、或者存在更优的索引被误选。

  • 运行 ANALYZE TABLE table_name 更新统计信息,尤其在大批量导入后
  • 对低基数字段(如状态码、开关标志)建索引意义不大,除非配合高选择性条件(如 WHERE status = 'processing' AND updated_at > NOW() - INTERVAL 1 HOUR
  • FORCE INDEX 是临时手段,不能替代问题定位;真正要查的是为什么优化器没选对——通常得结合 SHOW INDEXEXPLAIN 对比评估
EXPLAIN SELECT id, name FROM users WHERE deleted = 0 AND created_at > '2024-01-01';

索引设计不是一劳永逸的事。表结构变、数据分布变、查询模式变,原来高效的索引可能变成瓶颈。重点不是堆索引,而是理解每条慢查询背后的访问路径和数据特征。

https://www.php.cn/faq/1968207.html

发表回复

Your email address will not be published. Required fields are marked *