网站慢很大一部分瓶颈来自数据库:慢查询、索引失效、大表扫描、连接过多、IO 压力大。优化分为索引优化、SQL 语句优化、表结构设计、数据库配置、架构层优化、业务层规避六个层面。
一、索引优化(最高性价比)
索引本质是以空间换查询时间,不是越多越好。
给 WHERE、JOIN、ORDER BY、GROUP BY 字段建索引
联合索引遵循最左前缀原则,把过滤性高的字段放前面。
避免:
select * from table where a=? and b=?,只给 b 建索引。
避免索引失效场景
字段做运算、函数:
where year(create_time)=2026→ 改成范围查询create_time between '2026‑01‑01' and '2026‑12‑31'隐式类型转换:字符串字段用数字查询,索引失效
like '%关键词'前缀通配符不走 B + 树索引or两边字段只有一边有索引,容易失效
不要过度建索引 索引会减慢
INSERT/UPDATE/DELETE,写频繁业务少建索引;单表索引建议控制在 5‑8 个以内。覆盖索引 查询字段全部包含在索引里,不需要回表。
-- 建立联合索引(name,phone) select name,phone from user where name='xxx';使用
explain分析执行计划 重点看:type尽量到ref/range,避免ALL全表扫描;rows扫描行数越小越好;Extra避免Using filesort、Using temporary。

二、SQL 语句优化
拒绝 select *,只查询需要的字段,减少网络传输、内存占用。
分页大偏移量优化
-- 慢:偏移很大,扫描前面大量行
select * from article order by id limit 100000,10;
-- 优化:主键过滤
select * from article where id > 100000 order by id limit 10;
减少 join 数量,多表 join 会膨胀中间结果集;大表尽量不要 join 大表。
避免在循环里执行 SQL(N+1 问题),改成批量查询。
// 坏:循环查库
for(Long id:idList){ queryById(id); }
// 好:in批量一次查出
select * from user where id in (?,?,?)
in 集合不要过大,几千条以上拆分批次。
避免不必要排序、分组;尽量利用索引完成 order by、group by,避免
Using filesort。事务不要写太大,大事务会锁表、长连接、回滚日志暴涨,拆分小事务。
三、表结构设计优化
字段类型尽量小
能用
int不用bigint;能用varchar(64)不用varchar(1000)时间优先
datetime,不要字符串存时间;布尔用tinyint
大字段拆分 text、blob 大字段拆到独立副表,主表查询不加载大文本,减少内存 IO。
适度反范式:读多写少场景,冗余少量字段减少 join,牺牲一点一致性换查询速度。
大表做分表
水平分表:按时间、用户 ID 哈希拆分,单表控制百万‑千万级别
垂直分表:把低频大字段拆分出去
定时清理历史冷数据,避免表无限膨胀。
四、数据库配置优化(MySQL 示例)
需要结合服务器内存,不要盲目抄参数。
innodb_buffer_pool_size:InnoDB 最重要参数,物理内存 50%‑70%,把热点数据放内存,减少磁盘 IO。join_buffer_size、sort_buffer_size:每个连接独立分配,不要设置过大,防止内存暴涨。开启慢查询日志
slow_query_log,捕获执行超过阈值(比如 1 秒)的 SQL,定位慢 SQL。连接池:数据库连接不是越大越好,
max_connections不要几千,一般几百足够;应用侧连接池(HikariCP)合理配置。innodb_flush_log_at_trx_commit:业务可接受短暂丢失可设为 2 提升写入性能,金融业务保持 1。
五、架构层面优化
读写分离 主库负责写,多个从库负责读;网站大部分是读请求,读流量分摊到从库。
引入缓存,减少数据库访问
Redis 缓存热点数据:首页、商品、配置、高频查询结果。
缓存策略:缓存穿透、击穿、雪崩做好防护。
核心思想:能缓存就不去查 DB。
大查询、统计报表不要跑主库,走从库、OLAP 库。
分库分表:数据量亿级别以上,使用 Sharding‑JDBC 等中间件做分库分表。
适当使用搜索引擎(Elasticsearch):模糊搜索、全文检索不要丢给 MySQL。

六、业务与运维层面
定期分析慢 SQL,迭代优化,业务迭代很容易新增烂 SQL。
定期做表优化
OPTIMIZE TABLE,整理碎片(InnoDB 慎用,会锁)。避免高峰期做大表 DDL,大表改字段使用在线 DDL 工具。
监控数据库指标:QPS、TPS、慢查询数量、连接数、锁等待、磁盘 IO,提前发现瓶颈。
简单排查流程(网站变慢时)
打开慢查询日志,找到耗时最高 SQL
explain看执行计划,判断是否全表扫描、索引失效优先补索引、改写 SQL;SQL 改不动考虑加缓存
数据量过大:分表 / 读写分离;硬件瓶颈升级磁盘(SSD)
典型案例
网站首页加载慢,排查发现首页循环 N+1 查询,加上没有索引,单 SQL 扫描几十万行。 优化:批量查询 + 建立联合索引 + Redis 缓存首页数据,响应时间从 2‑3s 降到几十 ms。
本文原创作者:易君召,详见:https://www.yijunzhao.cn/authors/yijunzhao,转载请注明出处。
原文链接
欢迎访问 小易撩挨踢