SELECT *在大表上变慢主因是全表扫描,因缺失索引或索引失效(如函数、运算、类型转换),导致I/O瓶颈;宽表还易触发临时表和文件排序。

为什么 SELECT * 在大表上会突然变慢
不是因为查询本身复杂,而是数据库被迫做全表扫描。没有合适索引时,MySQL 必须逐行读取磁盘页,I/O 成为瓶颈。尤其当 WHERE 条件字段没建索引、或用了函数/表达式(如 WHERE YEAR(created_at) = 2023),索引就失效了。
- 避免在索引列上使用函数、类型转换或运算,例如
WHERE price + 10 > 100会让price索引失效 -
SELECT *在宽表中还可能触发临时表和文件排序,用EXPLAIN查看Extra字段是否出现Using filesort或Using temporary - 联合索引要注意最左前缀原则:对
(a, b, c)建索引,WHERE b = 1 AND c = 2无法命中,但WHERE a = 1 AND b = 2可以
EXPLAIN 输出里哪些字段真正影响性能判断
重点关注 type、key、rows 和 Extra 四个字段,它们直接反映执行路径质量。
-
type值从好到差:const≈eq_ref>ref>range>index>ALL;出现ALL基本等于全表扫描 -
key为空说明没走索引;若非空但rows值远大于实际结果数,可能是索引选择性差(比如对性别字段建索引) -
Extra中出现Using index condition是好的(ICP 下推),但Using where; Using index表示覆盖索引,而Using filesort就得警惕:ORDER BY 没走索引或顺序不匹配
什么时候该建联合索引而不是单列索引
当多个字段经常同时出现在 WHERE、ORDER BY 或 GROUP BY 中,且顺序稳定时,联合索引能显著减少索引数量和维护开销。
免费的开源程序长期以来,为中国的网上交易提供免费开源的网上商店系统一直是我们的初衷和努力奋斗的目标,希望大家一起把MvMmall网上商店系统的免费开源进行到底。2高效的执行效率由资深的开发团队设计,从系统架构,数据库优化,配以通过W3C验证的面页模板,全面提升页面显示速度和提高程序负载能力。3灵活的模板系统MvMmall网店系统程序代码与网页界面分离,灵活的模板方案,完全自定义模板,官方提供免费模
- 例如高频查询是
SELECT name FROM user WHERE status = ? AND city = ? ORDER BY created_at DESC,优先建(status, city, created_at)联合索引,而非三个单列索引 - 把等值条件字段放前面,范围/排序字段放后面:
(a = ?, b > ?, c ORDER BY)→ 索引应为(a, b, c),不是(a, c, b) - 注意区分「覆盖索引」需求:如果只查索引字段(如
SELECT status, city FROM user WHERE ...),联合索引还能避免回表
索引不是越多越好:写入变慢和空间膨胀怎么权衡
每个索引都是 B+ 树,INSERT/UPDATE/DELETE 都要同步更新所有相关索引。业务高峰期大量写入时,过多索引会明显拖慢响应,且占用更多磁盘与内存。
- 单表索引数建议控制在 5–7 个以内;可通过
information_schema.STATISTICS查看各索引的INDEX_COMMENT和使用频率(需开启userstat或用performance_schema) - 删除长期未被使用的索引:比如某索引在
sys.schema_unused_indexes视图中持续多日无记录 - TEXT/BLOB 字段不能直接建索引,要用前缀长度(如
content(100)),但前缀过短会导致重复率高、选择性差
SHOW INDEX FROM orders\G -- 查看索引字段顺序、是否唯一、基数(Cardinality)等,基数越接近行数,索引区分度越高
索引优化本质是让 MySQL 少读磁盘、少算中间结果。很多“慢查询”背后不是 SQL 写得差,而是数据分布变了、统计信息没更新、或者上线后业务查询模式偏移了——这些细节比“加个索引”更难察觉。









