Files
UHD_Media_Tool/packages/db/migrations/0089_db_perf.ts
T
rootandClaude Opus 5.5 9fffee16c8 perf(db): 标题模糊匹配改用 % 运算符走 trigram 索引,巡检回填加部分索引,删除无用索引
- 别名 / 资源标题模糊匹配原来写 similarity(x, q) >= t,函数调用用不上 trigram 索引;改为
  x % q and similarity(x, q) >= t(% 缺省阈值 0.3 不高于各处阈值,结果相同)。source_release 标题搜索
  在部署规模(8440 行)从约 75 ms 降到 0.7 ms
- 调度器每 15 秒的巡检回填原来整扫 scheduled_job_run:迁移 0089 加部分索引 scheduled_job_run_harvest_idx
- 迁移 0089 删除没有任何查询会用到的 content_unit_air_date_idx;镜像带 pg_stat_statements 时建扩展,
  没有或权限不够时跳过,不让迁移失败
- gen:types 跳过扩展自带的视图(public.pg_stat_statements)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
2026-10-06 20:24:07 +08:00

46 lines
1.9 KiB
TypeScript

import type { Kysely } from "kysely";
import { execDdl } from "../src/migration-helpers.ts";
// 数据库性能与可观测(docs/runbook/storage.md「数据库性能」):
// - scheduled_job_run_harvest_idx:调度器每 15 秒回填巡检结果(scheduler.harvest),原来每次全表扫运行历史;
// 部分索引只含「有 agent_run 且尚未回填」的行,通常为 0~几行;
// - 删除 content_unit_air_date_idx:没有任何查询按 air_date 过滤或排序(订阅日历在内存里按日期筛),
// 按作品取单元走 content_unit_entity_numbering_idx;
// - pg_stat_statements:镜像自带时才建(库级共享对象,放 public;down 不卸载)。要真正采集还需要
// postgres 以 shared_preload_libraries=pg_stat_statements 启动(docker-compose.yml),没有预加载时只是查询会报错,
// 状态页按「未启用」处理。没有该扩展或权限不够时跳过,不让迁移失败。
// biome-ignore lint/suspicious/noExplicitAny: 迁移不依赖应用表类型
export async function up(db: Kysely<any>): Promise<void> {
await execDdl(
db,
`
create index if not exists scheduled_job_run_harvest_idx on scheduled_job_run (agent_run_id)
where agent_status is null and agent_run_id is not null;
drop index if exists content_unit_air_date_idx;
do $$
begin
if exists (select 1 from pg_available_extensions where name = 'pg_stat_statements') then
begin
create extension if not exists pg_stat_statements with schema public;
exception when others then
raise notice 'pg_stat_statements 未安装:%', sqlerrm;
end;
end if;
end $$;
`,
);
}
// biome-ignore lint/suspicious/noExplicitAny: 同上
export async function down(db: Kysely<any>): Promise<void> {
await execDdl(
db,
`
drop index if exists scheduled_job_run_harvest_idx;
create index if not exists content_unit_air_date_idx on content_unit (media_entity_id, air_date) where air_date is not null;
-- 扩展为库级共享对象,down 不卸载
`,
);
}