MySQL性能优化实战:慢查询到毫秒响应的全链路突破
|
MySQL性能优化实战:慢查询到毫秒响应的全链路突破——这标题不是喊口号,是我2026年5月在「智医云」三甲医院SaaS平台上线前压测现场写下的日志首行。当时急诊分诊系统查询患者历史处方平均耗时4.7秒,P99卡在6.2秒,医生点一次“查看既往用药”就要等得看表。
文章配图,仅供参考 我盯了整整72小时的Percona Toolkit输出、pt-query-digest解析出的TOP3慢SQL里,有一条JOIN了5张表、含3个子查询、WHERE里还套了UNIX_TIMESTAMP(FROM_UNIXTIME())这种双重转换的语句——它占全部慢查量的63.8%,但开发者坚称“测试环境从没超200ms”。后来发现测试库用的是MyISAM引擎,而生产切到了InnoDB,索引统计信息偏差率达41%,OPTIMIZER_TRACE显示它选错了驱动表。这事我记着:技术栈迁移不配套数据校验,再新的优化工具也救不了设计缺陷。 2026年5月17日14:03,我们把原生JSON字段的模糊搜索改成了双写:业务层写入时同步生成normalized_drug_code(如"001-amlodipine-5mg")并建前缀索引;同时给MySQL 8.0.33启用了ngram全文解析器——但没立刻生效。直到凌晨2点重启mysqld时漏掉了--collation-server=utf8mb4_0900_as_cs参数,导致ngram tokenizer始终返回空token。这个细节连官方文档都藏在“Section 12.10.7”的脚注第三行里。折腾11小时后,处方搜索P95降到89ms。新技术?确实新。但新到连错误提示都不报错,只默默降级为LIKE %xxx%。 失败最狠的是2026年5月8日那次分区表改造。我把就诊记录表按MONTH拆成36个PARTITION,结果发现INSERT并发突增时MDL锁等待飙升至平均1.8秒——因为每个INSERT都要校验所有分区的定义元数据。后来翻到Oracle Bug#10294756才发现,MySQL 8.0.28+对RANGE COLUMNS分区的元数据锁粒度根本没优化。最终退回到按YEAR+HASH(weekofyear)混合分区,锁等待压到17ms。这事教会我:文档写的“支持高并发分区插入”,不等于“支持你的并发模式”。 最让我意外的是Query Rewrite Plugin的实际效果。我们在MySQL 8.0.33上部署了自定义规则,把SELECT FROM lab_result WHERE create_time > DATE_SUB(NOW(), INTERVAL 7 DAY)自动重写为SELECT id, patient_id, report_status, create_time FROM lab_result WHERE create_time > '2026-05-10 00:00:00'——硬编码日期值。实测TPS提升3.2倍。但它有个坑:重写后EXPLAIN的rows预估永远不准,DBA监控告警阈值全乱套了。现在我们的Prometheus告警规则里专门加了一条:当rewrite_enabled=1且rows_estimated > 500000时,强制触发人工review。这点没人提过。 我们上线了实时慢查熔断:当单条SQL执行超800ms且连续3次,ProxySQL自动注入SQL_NO_CACHE并路由到只读池隔离——但这在2026年5月22日医保结算高峰时误熔断了37次。根因是时钟漂移:应用服务器NTP偏移1.2秒,而ProxySQL依赖本地时间做滑动窗口统计。现在我们强制所有节点走chrony + PTP硬件时钟同步。这事说明:再好的链路控制,也架不住基础时间不同步。 真实世界没有银弹。 2026年5月至今,我手头还有4个未解问题:① InnoDB page cleaner线程在Buffer Pool命中率>99.2%时反而出现latch争用;② MySQL 8.0.33的UNION ALL临时表在并行执行计划下内存估算误差超300%;③ pt-deadlock-logger抓不到某些跨XA事务的死锁;④ 我们自研的SQL健康度评分模型,在OLAP类报表查询上F1-score只有0.61。这些我打算下周带两瓶冰啤酒去杭州阿里云总部找内核组聊聊——他们5月刚开源的那个Page Cleaner调度补丁,我怀疑能解第一个问题。 (编辑:均轻资讯网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


MySQL事务控制无障碍设计指南(技术SEO优化版)
VR开发编译技巧与性能优化实战精要