先说个最容易被忽略的——字段类型的选择。上次我们有个表用存手机号,索引建得妥妥的,查询却慢成狗。后来用一看,索引根本没生效。排查半天才发现是字符集校对问题,的排序规则导致全表扫描。改成并指定字符集,速度直接起飞。时间戳字段更是个重灾区,很多人爱用,其实它的时区转换特性经常在跨时区部署时埋雷。现在我们都统一用存Unix时间戳,应用程序自己做转换,省心太多。
关于索引,有个血泪教训。有张百万级用户表,我们在,,上建了联合索引。某天运营同事查“最近7天特定分组的不活跃用户”,用查询,结果索引选择性最好的字段因为值分布太集中(90%都是0),实际效果还不如单用做索引。后来改成的顺序,查询时间从3秒降到0.1秒。这里有个口诀:“等值查询字段放最左,范围查询字段尽量靠右”。
联表查询的坑更深。最近优化个三表关联查询,A表50万条,B表300万条,C表80万条。最初写法是,在测试环境没问题,上线就崩。用检查发现大量时间花在。最后拆成两个步骤:先用子查询过滤出最小结果集,再用临时表做关联,耗时从12秒降到0.8秒。现在团队硬性规定:联表不得超过三层,超过就必须拆解。
事务隔离级别这块也容易踩雷。我们财务系统遇到过更诡异的问题:RR级别下,两个并发事务更新同一批数据,明明用加了锁,还是出现超额扣款。后来抓包发现是间隙锁和临键锁的联合作用导致死锁。解决办法是在事务内先用确认数据范围,再批量更新。建议所有金额操作都要在应用层做二次校验,数据库的锁只能作为最后防线。
备份恢复这块吃过亏的请举手。有次主从同步延迟,DBA直接在主库改了表结构,结果从库卡住。尝试用导出再导入,没想到触发器把业务数据搞乱了套。现在我们的标准流程是:任何DDL操作前先用,每周用做逻辑备份,同时开二进制日志实时同步到异地。记住,没经过恢复演练的备份都是假备份。
性能监控方面,别光盯着慢查询日志。最近我们发现个规律:当突然飙升时,八成是有人跑了大报表。后来在监控系统设置了阈值,超过200就自动发告警。推荐重点监控的指标:线程连接数、临时表数量、锁等待时间,这些比CPU使用率更能提前发现问题。
最后说个运维细节:有次凌晨做数据迁移,执行到一半被运维系统kill了,说是执行时间超时。后来才知道默认的设置太短。现在这类操作都放在维护窗口手动执行,提前算好预估时间。提醒大家,任何超过10分钟的DDL操作,务必先在备库测试,同时准备好回滚方案。
其实MySQL用久了就会发现,真正的高手不是能写出多复杂的SQL,而是懂得在合适的时候做减法。有时候多写几行代码,换个思路,比死磕SQL优化更有效。记住,数据库就是个工具箱,别把螺丝刀当锤子用。
1782

被折叠的 条评论
为什么被折叠?



