fix(messages): 聊天记录大对话超时——DESC首屏+keyset游标+群聊直达索引
用户报:聊天记录多时「聊天记录加载失败:请求失败 (ECONNABORTED)」(2026-09-07)。 服务器 EXPLAIN ANALYZE 实测两级根因: - 单聊 1 万条:ASC 末页 OFFSET 10486 逐条回表 2515ms(DESC LIMIT 15ms,167 倍); - 群聊 16,290 条:查询刻意不带 owner(chat_group 去重后 owner 错位),现有 (channel,owner,room,timestamp) 索引被 owner 挡住,退化到 room 单列索引+ filter+filesort——count 4.7s/首页 5.1s/末页 10.7s;真凶群 53132846289@chatroom 40,863 条,三段串行 ~40s 必撞前端 axios 15s 超时。 修法(不动共享 MySQL 配置,沿用既往修复模式): 1. 迁移 e6f7a8b9c0d1:message 补 (channel, room_id, timestamp) 索引,群查询 seek+排序直达+覆盖 count;模型侧双声明防 autogenerate 反 DROP。 2. /api/messages 加 order=asc|desc(默认 asc 不变)与 before_ts/before_id keyset 游标(成对,单传 422)——排序列 (timestamp,msg_id) 全序,平手按 msg_id 决胜,游标页恒 O(page_size)。 3. 前端 ChatMain/ChatTimeline 首屏改「order=desc 取最新 50 反转」单请求 (原 page1 拿 total+深 OFFSET 末页两请求),「加载更多」改游标上翻; hasMoreOlder=已加载<总数。SessionPane 搜索等 order=asc 默认路径不受影响。 本地实测(37,532 条群):desc 首页 0.39s、游标上翻 0.24s,浏览器真机 渲染+上翻 150 条无错。测试 8 增(desc/游标/平手边界/422/窗口叠加/ 前端流程不变式),全量 601 绿。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -434,6 +434,19 @@ class Message(Base):
|
||||
"room_id",
|
||||
"timestamp",
|
||||
),
|
||||
# 群聊消息窗实际查询形如 ``channel=? AND room_id=? ORDER BY timestamp``
|
||||
# (不带 owner——chat_group 按 room 去重后 owner 与消息归属错位,见
|
||||
# ChatMain queryFor)。上面的索引被 owner 挡住前缀用不上,优化器退化到
|
||||
# room 单列索引 + filter + filesort:2026-09-07 服务器实测 4 万条群
|
||||
# count 4.7s / 首页 5.1s / 末页 10.7s,串行撞前端 15s 超时
|
||||
# (ECONNABORTED)。此索引让群查询与单聊同享 seek+排序直达。
|
||||
# 「模型+迁移双声明」防 alembic autogenerate 反 DROP。
|
||||
Index(
|
||||
"ix_message_channel_room_time",
|
||||
"channel",
|
||||
"room_id",
|
||||
"timestamp",
|
||||
),
|
||||
# 今日收发聚合热路径:channel= + owner IN + timestamp>= 定位当天消息
|
||||
# (customer 列表行内 send_today/receive_today)。上面两个索引把
|
||||
# timestamp 排在 talker/room 之后,时间范围无法直接 seek;MySQL 预编译
|
||||
|
||||
Reference in New Issue
Block a user