排行榜卡三秒、交易行搜索转圈五秒——慢查询是玩家能直接感知的性能债。慢查询治理的套路是三步:慢日志定位、执行计划找根因、改写或加索引收尾,十条典型慢 SQL 的改写范式覆盖九成场景。
---慢查询的捕获:超 200 毫秒入榜
setontimerex(72, 60)
function SlowLog.collect()
local rows = DB.query(
"SELECT query, exec_ms, rows_examined " ..
"FROM slow_log WHERE exec_ms > 200 " ..
"ORDER BY exec_ms DESC LIMIT 10")
for _, r in ipairs(rows) do
Ops.log(("慢查询 %dms 扫 %d 行: %s"):format(
r.exec_ms, r.rows_examined, r.query:sub(1, 80)))
end
end
慢日志按 200 毫秒的门槛捕获,每分钟输出前十名。执行时间与扫描行数的双指标定位根因:扫百万行返回十行的查询必是索引缺失,扫千行返回千行的查询是数据量本身的问题。捕获的样本按指纹聚合,同一形态的慢查询反复上榜只需治理一次。
---范式一:SELECT * 改按需取列
-- 慢:SELECT * FROM roles ORDER BY level DESC LIMIT 50
local top = DB.query(
"SELECT id, name, level FROM roles " ..
"ORDER BY level DESC LIMIT 50")
---范式二:函数包列让索引失效,改为范围条件
-- 慢:WHERE DATE(create_at) = '2026-09-21'
local rows = DB.query(
"SELECT COUNT(*) FROM item_log " ..
"WHERE create_at >= ? AND create_at < ?",
"2026-09-21 00:00:00", "2026-09-22 00:00:00")
十条范式的精华三条:SELECT * 改按需取列,网络与内存的传输量按需收缩;列上包函数(DATE、SUBSTR)让索引失效,改写成范围条件让索引活着;大分页的 LIMIT 100000,50 改成游标条件(WHERE id > 上次末尾 LIMIT 50),翻页越深越快的假象被游标打破。交易行搜索的组合条件用联合索引按最左前缀排列,价格的区间与品质的等值组合一索引吃下。索引的补充用执行计划验证:改动前后 EXPLAIN 的扫描行数对比,行数不降的索引是多余的写放大。
改写前后的耗时对比进工单,收益低于 30% 的改动不合并;慢查询的上榜数周报,治理的速度要跑赢业务的增长。
索引曾经加了一堆不见效,联合索引的列序与查询条件不符,最左前缀的规则吃透后一次到位。ORM 的隐式类型转换让索引失效,字符串列用数字比较全表扫描,类型的严格匹配写进评审。统计类的查询曾经直打主库,治理时顺带迁去从库,查询的治理与路由一并考虑。
慢查询的门槛按接口分级:交易行 300 毫秒、排行 500 毫秒,一刀切的门槛误伤长尾。索引的变更走评审与从库验证,写放大与查询收益的账一起算。十条范式的文档进新人培训,治理的能力要可复制。
本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
实战应用:用在哪里 沙巴克占领行会坐收税收却只进不出,非占领行会的玩家心里不平衡。税务官玩法把税收做成明账:占领行会对摆摊与…
实战应用:用在哪里 高端玩家婚姻系统只有仪式没有过程,社交绑定缺一个高光事件。比武招亲做成擂台玩法:擂主设擂摆彩头,攻擂者报…
实战应用:用在哪里 开服七日限时礼包发到第六天断了粮,9 月 1 日当天领奖按钮灰的,投诉当天破千。事故根因是一条数字日期循…
实战应用:用在哪里 玩家拔线不退游戏,连接半开着,人不在指令也没有,在线数虚高,容量预案被假数据带着跑。心跳探测给每个在线玩…
实战应用:用在哪里 周三发了合成系统补丁,周四又改强化概率,两条变更叠加后玩家分不清是哪个改出来的。发布日历把全月变更集中排…
实战应用:用在哪里 容量预案需要知道滚动一小时的副本进入峰值,而不是全天累计。滑动窗口用 60 个槽位每槽记一分钟的进入数,…