干这一行的人都知道,数据库慢起来能让人怀疑人生。明明业务逻辑没问题,SQL也写得挺顺眼,可一到高峰期,响应时间嗖嗖往上涨,CPU飙到90%以上,DBA的工位前围了一圈业务方催命。其实大多数性能问题,根源就那么几个:索引没用对、SQL写得糙、锁竞争太狠、配置参数是出厂默认值。这就像开车,你油门踩到底但手刹没松,再使劲也是白搭。今天这篇,咱们就把手刹松开,聊聊六个实打实的优化策略。

第一个策略,先别急着加机器,把慢查询日志打开看看。很多人一遇到性能问题,第一反应是加内存、加CPU,或者干脆多搞几台机器做读写分离。这思路不能说错,但大概率治标不治本。慢查询日志这东西,MySQL、PostgreSQL、SQL Server全都内置,你只需要花两分钟配置一下阈值,比如超过200毫秒的查询全记下来,跑个半小时再看,保证能发现几个“大胃王”。我见过一个案例,某系统每天凌晨跑报表,把一张千万级的大表全表扫描了三次,每次耗时四五十秒,日志里清清楚楚。业务方还以为是硬件不够,非要申请预算买新服务器,结果把一条SQL改成走索引,耗时直接降到两百毫秒。这就是典型的“药不对症,先看病因”。
第二个策略,索引别贪多,但要建在刀刃上。很多人听说索引能提速,于是见一个字段就建一个索引,甚至把组合索引当集邮。结果呢?写入变慢、存储膨胀、优化器反而不知道选哪个索引,偶尔还走错路。正确的做法是,先分析你的WHERE条件、JOIN字段和ORDER BY排序,找出高频查询的过滤条件,然后建联合索引,注意最左前缀原则。比如订单表,你经常查“用户ID + 状态 + 创建时间”,那就建一个(用户ID, 状态, 创建时间)的联合索引,顺序不能乱。还有个技巧,索引上尽量别用函数,比如WHERE DATE(createtime)='2024-01-01',这种写法索引直接失效,你得改成范围查询才行,createtime >= '2024-01-01' AND createtime < '2024-01-02'。细节决定成败,索引这东西,少而精比多而杂管用得多。
第三个策略,SQL语句本身要瘦身。很多慢查询不是表太大,而是你让它干了太多不该干的活。比如SELECT *,一次性把几十个字段全捞出来,哪怕你只用其中两个,数据库也得把整行数据读进内存。再比如子查询嵌套三层,明明可以用JOIN解决,非要写成IN (SELECT ...),优化器一懵,直接全表扫描。还有一点,分页查询用LIMIT 100, 20,这种写法会让数据库先读十万行再扔掉,效率极低。改成基于游标或者记录上次最大ID的方式,速度快得飞起。我见过一个电商后台,运营每天导出订单,SQL里有个大IN条件,里面塞了几千个ID,每次执行都卡死。后来改成临时表JOIN,秒出结果。SQL是写给数据库的指令,你指令写得越清晰、越直接,它执行得就越快。
第四个策略,硬件和配置参数别忽视,但别盲目调。数据库默认配置是给“能用”设计的,不是给“高效”设计的。拿MySQL的InnoDB来说,buffer pool大小默认只有128MB,你要是机器有32G内存,这简直是暴殄天物。把innodbbufferpoolsize调到物理内存的60%-70%,热点数据全在内存里,磁盘IO直线下降。还有连接数,max_connections默认151,并发一高就报“Too many connections”,但调太大也不一定好,每个连接都占内存和线程,建议结合机器配置和业务并发量来定。另外,binlog刷盘策略、redo log大小、临时表空间这些参数,都可以根据业务特性微调。但记住一个原则:先监控,后调参,别拿生产环境当实验田。改完参数要压测,验证有效再上正式环境。
第五个策略,读写分离和分库分表,这是大招,但别轻易用。当单表数据量超过千万甚至上亿,索引再好也撑不住,这时候就得考虑拆分。读写分离适合读多写少的场景,主库负责写入,从库负责查询,用中间件或者应用层路由实现。分库分表则更复杂,按用户ID或者时间维度分成多个库表,比如订单表按月分表,或者按用户ID取模分16个库。但这招一旦用上,跨库查询、分布式事务、全局ID生成这些坑全来了。所以我的建议是,分库分表是最后的手段,先用尽前面五个优化,实在不行再上。而且拆分前一定要做好数据迁移方案和回滚预案,不然上线当天就是事故日。
第六个策略,缓存系统是数据库的“外挂”。很多数据库压力大,根源是重复查询太多。同一份数据,十个人查八遍,数据库累死累活算八次,其实第一次算完结果放缓存里,后面七次直接命中缓存,秒回。Redis就是个经典搭配,把热点数据、高频查询结果、用户会话缓存起来,数据库的QPS能降一个数量级。但缓存也有讲究,你得想好过期策略和一致性方案。比如先更新数据库,再删除缓存,这种“Cache Aside”模式比较稳妥。千万别把缓存当万能药,缓存雪崩、缓存穿透、缓存击穿,每一个都能让你头疼。缓存是加速器,不是保险箱,该兜底还得兜底。
说了这么多,你会发现这六个策略其实环环相扣。慢查询日志告诉你问题在哪,索引和SQL优化解决单条查询的效率,配置参数和硬件调优提升整体吞吐,读写分离和分库分表解决数据量膨胀,缓存则挡住了大量重复请求。没有哪个策略是银弹,但组合起来,数据库的性能天花板能抬高一大截。送你一句话:优化数据库,先别急着花钱加机器,花点时间看日志、改SQL、调索引,往往花小钱办大事。这套方法论,你自己跑一遍,就知道多值了。


