SQL 稳定性建设的长期策略

SQL稳定性需在开发、测试、上线、运行四阶段持续嵌入约束与反馈;审核须前置至IDE和CI阶段,集成轻量规则与EXPLAIN检查;慢查询归因需综合lock_time等多维度指标;索引变更需影子库验证与流量观察;应用层缓存失效可能压垮SQL稳定性。

SQL 稳定性不是靠一次治理或一个工具能解决的,它需要在开发、测试、上线、运行四个阶段持续嵌入约束和反馈机制。

SQL 审核必须前置到 IDE 和 CI 阶段

等 SQL 到线上才拦截,已经晚了。真正有效的审核要发生在开发者敲完 SELECT 的那一刻。

  • 在 VS Code 或 IntelliJ 插件中集成轻量规则(如禁止无 WHEREUPDATE/DELETE、检测全表扫描风险的 LIKE '%xxx'
  • CI 流水线里跑 EXPLAIN 模拟执行计划,对扫描行数超 10000 或出现 type=ALL 的 SQL 直接失败构建
  • 避免把所有规则塞进数据库代理层——延迟高、误报多、开发者感知弱

慢查询归因不能只看 execution_time

很多“慢查询”实际卡在锁等待、磁盘 IO 或连接池耗尽,单看执行时间会误导优化方向。

  • 采集时必须同时记录 lock_timerows_examinedtmp_tablescreated_tmp_disk_tables
  • state=Waiting for table metadata lock 这类错误码单独告警,它往往意味着 DDL 与查询冲突,而非 SQL 本身问题
  • pt-query-digest 聚合时,按 --group-by fingerprint 而非原始 SQL,否则参数化差异会让同一类问题分散不可见

索引变更必须配套回滚验证和流量观察

加索引不等于性能提升,尤其在写多读少或存在冗余索引的场景下,可能反而拖慢 INSERTUPDATE

  • 上线前用影子库回放真实流量,对比 QPSavg_latencyinnodb_row_lock_waits
  • 索引命名强制带业务标识,例如 idx_order_user_status_created,避免后期无法判断用途而不敢清理
  • 监控新增

    索引 72 小时内的 Handler_read_nextHandler_read_rnd_next 变化,突增说明索引未被有效利用

最常被忽略的是应用层缓存与 SQL 稳定性的耦合:当缓存失效风暴触发大量相同 SQL 请求,再稳定的执行计划也会被并发压垮。这要求 DBA 和后端开发必须共享慢查询 TopN 和缓存击穿日志,而不是各自看各自的指标。