索引需匹配查询条件而非越多越好。WHERE、JOIN、ORDER BY、GROUP BY才是索引生效场景;联合索引遵循最左前缀原则;避免在索引列上用函数操作。

索引不是越多越好,而是要匹配查询条件
很多开发者一听说“加索引能提速”,就给所有字段都加上 INDEX,结果反而拖慢写入、增大存储、让优化器选错执行计划。MySQL 的 WHERE、JOIN、ORDER BY、GROUP BY 才是索引真正起效的场景。
实操建议:
- 用
EXPLAIN看查询是否命中索引,重点关注type(最好是ref或range)、key(实际使用的索引名)、rows(扫描行数) - 联合索引要遵循最左前缀原则:
INDEX(a, b, c)能用于WHERE a=1、WHERE a=1 AND b=2,但不能用于WHERE b=2 - 避免在索引列上做函数操作,比如
WHERE YEAR(create_time) = 2024会让索引失效;改用范围查询:WHERE create_time >= '2024-01-01' AND create_time - 区分
SELECT *和只查必要字段——宽表 + 覆盖索引(Extra显示Using index)能显著减少回表开销
慢查询日志必须开,但不能只靠它“事后救火”
slow_query_log = ON 是调优起点,但光打开不够。默认 long_query_time = 10 秒,对线上服务来说早已太晚。真实业务中,响应超过 1 秒的查询就该被关注。
实操建议:
- 把
long_query_time设为0.5(单位秒),并开启log_queries_not_using_indexes = ON,强制记录没走索引的查询 - 用
mysqldumpslow或pt-query-digest分析日志,优先处理Count高、Avg_query_time长、Rows_examined大的 SQL - 注意:开启慢日志本身有 I/O 开销,生产环境建议用
log_output = TABLE(写入mysql.slow_log表),再定时归档,避免影响磁盘性能
innodb_buffer_pool_size 不等于“越大越好”,得看物理内存和工作集
这个参数控制 InnoDB 缓存数据页和索引页的内存大小。设得太小,频繁磁盘读取;设得太大,可能挤占 OS 缓存或触发 swap,反而卡顿。
友邻phpB2B电子商务系统是一套用PHP开发的B2B电子商务系统应用程序,本系统基于PHP+MySQL开发, 采用优秀的MVC架构思想,同时本系统采用了流行的Smarty模板技术,静态模板与动态程序完全分离,系统自带十余个内容丰富的调用标签,同时可自由扩展各种插件或其他功能,秉承开源、开放的原则,是目前搭建B2B行业门户网站最好的程序。安装说明首先请确保目录attachment、data、con
实操建议:
- 通用经验公式:
innodb_buffer_pool_size = 总内存 × 0.7 ~ 0.8,但前提是你的热数据(活跃访问的表+索引)能放进这个池子 - 检查命中率:
SELECT (1 - (SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_reads') / (SELECT variable_value FROM information_schema.global_status WHERE variable_name = 'Innodb_buffer_pool_read_requests')) * 100 AS hit_rate;
持续低于 95%,说明池子可能不够或查询不集中 - 若实例混跑多个 MySQL 或其他服务(如 Redis、Java 应用),务必预留足够内存给 OS 和其他进程,否则
OOM killer可能直接杀掉 mysqld
UPDATE/DELETE 不加 WHERE 条件或没走索引,是线上事故高发区
这类语句一旦没走索引,会锁全表(尤其在 RR 隔离级别下),阻塞后续所有 DML,甚至拖垮整个库。比慢查询更危险的是“静默慢更新”——没有报错,但锁了 10 分钟。
实操建议:
- 上线前必须确认
EXPLAIN结果中的type不是ALL,且rows在可接受量级(比如几万以内) - 批量更新/删除分批做,加
LIMIT并用主键范围控制,例如:DELETE FROM orders WHERE status = 'pending' AND id BETWEEN 10000 AND 20000;
-
开发环境启用
sql_safe_updates = ON,强制要求UPDATE/DELETE必须带WHERE且含键值条件,避免误删 - DDL 操作(如加索引)在大表上也等效于全表扫描+重建,务必在低峰期用
ALGORITHM=INPLACE(5.6+)或工具如pt-online-schema-change
实际调优中最容易被忽略的,是业务逻辑层的聚合压力——比如一个接口反复查同一张配置表几十次,或者用 SELECT * 拉回几百列却只用其中 2 列。数据库只是执行者,真正的瓶颈常常藏在应用怎么用它。










