perf(management): message补无渠道前缀索引——修驾驶舱channel=all超时34s→1.3s
该回未回决赛圈点查(owner+talker定位末条消息)在channel=None时无渠道 前缀条件,现有索引全以channel打头用不上,服务器100万行实测dashboard 34~37s撞前端15s超时(ECONNABORTED);补(owner,talker,timestamp)索引 后实测1.3~1.8s。服务器已先行手工建索引止血,本迁移幂等兜底对齐。 模型+迁移双声明防autogenerate反DROP
This commit is contained in:
@@ -537,6 +537,18 @@ class Message(Base):
|
|||||||
"ix_message_fetched_at",
|
"ix_message_fetched_at",
|
||||||
"fetched_at",
|
"fetched_at",
|
||||||
),
|
),
|
||||||
|
# 该回未回决赛圈点查(owner+talker 定位末条消息)在 channel=None
|
||||||
|
# (全平台计数——管理驾驶舱 action_counts 复用)时无渠道前缀条件,
|
||||||
|
# 上面全部以 channel 打头的索引用不上,逐候选退化扫表+filesort:
|
||||||
|
# 2026-09-10 服务器实测 dashboard 34~37s 撞前端 15s 超时
|
||||||
|
# (ECONNABORTED);补无渠道前缀索引后 1.3~1.8s(100 万行在线建
|
||||||
|
# 索引 49s)。「模型+迁移双声明」防 alembic autogenerate 反 DROP。
|
||||||
|
Index(
|
||||||
|
"ix_message_owner_talker_time",
|
||||||
|
"owner_account_id",
|
||||||
|
"talker_id",
|
||||||
|
"timestamp",
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"""message 补无渠道前缀索引 (owner_account_id, talker_id, timestamp)
|
||||||
|
|
||||||
|
Revision ID: d8e9f0a1b2c3
|
||||||
|
Revises: c9d0e1f2a3b4
|
||||||
|
Create Date: 2026-09-10
|
||||||
|
|
||||||
|
背景:该回未回决赛圈点查在 channel=None(管理驾驶舱 action_counts)时
|
||||||
|
无渠道前缀条件,现有索引全部以 channel 打头用不上——服务器 100 万行
|
||||||
|
实测 dashboard 34~37s 撞前端 15s 超时;索引落地后 1.3~1.8s。
|
||||||
|
幂等:sa.inspect 先查,存在即跳过(服务器已先行手工建同名索引,本迁移
|
||||||
|
兜底对齐 schema 版本)。「模型+迁移双声明」防 autogenerate 反 DROP。
|
||||||
|
"""
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from alembic import op
|
||||||
|
|
||||||
|
revision: str = "d8e9f0a1b2c3"
|
||||||
|
down_revision: str | Sequence[str] | None = "c9d0e1f2a3b4"
|
||||||
|
branch_labels: str | Sequence[str] | None = None
|
||||||
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
_IDX = "ix_message_owner_talker_time"
|
||||||
|
|
||||||
|
|
||||||
|
def _has_index(bind) -> bool:
|
||||||
|
insp = sa.inspect(bind)
|
||||||
|
if not insp.has_table("message"):
|
||||||
|
return False
|
||||||
|
return _IDX in {ix["name"] for ix in insp.get_indexes("message")}
|
||||||
|
|
||||||
|
|
||||||
|
def upgrade() -> None:
|
||||||
|
if not _has_index(op.get_bind()):
|
||||||
|
op.create_index(_IDX, "message",
|
||||||
|
["owner_account_id", "talker_id", "timestamp"])
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade() -> None:
|
||||||
|
if _has_index(op.get_bind()):
|
||||||
|
op.drop_index(_IDX, table_name="message")
|
||||||
Reference in New Issue
Block a user