Files
KCGL/db_migrations/add_active_location_indexes.sql
yueli d1694bf245 perf(stocktake): 去掉库位树的全展开渲染,并为推荐查询补索引
业务反馈切到抽盘面板与点【获取推荐】时卡顿。实测定位:

【真正的原因在前端】先跑 EXPLAIN ANALYZE 排除了后端 ——
推荐查询在当前数据量下仅耗时 1.3ms,全走 Seq Scan + Hash Join,
Buffers shared hit=161 全部命中缓存。所以卡顿来自 DOM:
el-tree 原先带 default-expand-all,会把全库 3371 个库位节点一次性铺进 DOM。

去掉 default-expand-all 后初始只渲染根节点。勾选状态与 getCheckedNodes
不受影响 —— el-tree 的 Node store 会预先构建全树,展开与否只影响 DOM。

【索引仍补上,但说明白】实测 pg_indexes:stock_* 三表的 warehouse_location
已有索引,但 trans_outbound / trans_borrow 只有主键,时间字段与
(source_table, stock_id) JOIN 键都缺;三张库存表的时间字段也缺。
新增迁移 add_active_location_indexes.sql 补 7 个索引。

诚实说明写在迁移头部:当前数据量下加索引后本查询**仍会走 Seq Scan**,
这是小表下的正确计划,索引是为 90 天/半年后的数据增长做前瞻,不是修当前的慢。

【loading 状态】treeLoading / recLoading 已在既有实现中就位并闭环在
try/finally 中,分别绑在 el-tree 的 v-loading 与【获取推荐】按钮的 :loading 上,
本轮复核确认,未做无谓改名。

实测: 索引后执行计划仍为 Seq Scan,Execution Time 0.769ms(预期内)
2026-09-11 14:38:40 +08:00

54 lines
2.4 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- =============================================================================
-- 一次性迁移:为「活跃库位推荐」查询补索引
--
-- 背景
-- get_active_locations(company_name, days, top_n) 要扫三张流水/库存表的
-- 时间字段,并逐一 JOIN 回库存表取库位:
-- trans_outbound.outbound_time → JOIN stock_* ON (source_table, stock_id)
-- trans_borrow.borrow_time → JOIN stock_buy ON (source_table, stock_id)
-- stock_buy.in_date / stock_semi.production_date / stock_product.production_date
--
-- 现状(实测 pg_indexes
-- stock_buy / stock_semi / stock_product 的 warehouse_location 已建索引
-- trans_outbound、trans_borrow 只有主键索引,时间字段和 (source_table,
-- stock_id) JOIN 键都没有索引;三张库存表的时间字段也没有索引。
--
-- 为什么现在加(诚实说明)
-- 实测 EXPLAIN ANALYZE当前数据量下trans_outbound 900 行、stock_buy 2018 行)
-- 该查询耗时仅 1.3ms,且全走 Seq Scan + Hash Join —— 这是小表下的**正确**
-- 计划,索引也不会被选中。所以本次加索引不是为了修当前的慢,而是为
-- 90 天/半年后的数据增长做前瞻,避免那时才临时补。
-- 加完索引后本查询在当前数据量下仍会走 Seq Scan属预期行为。
--
-- 执行: docker exec -i inventory_db psql -U test -d inventory_system < 本文件
-- =============================================================================
BEGIN;
-- 出库:按时间窗口过滤
CREATE INDEX IF NOT EXISTS ix_trans_outbound_time
ON trans_outbound(outbound_time);
-- 出库:回查库存表取库位的 JOIN 键
CREATE INDEX IF NOT EXISTS ix_trans_outbound_source_stock
ON trans_outbound(source_table, stock_id);
-- 借用:按时间窗口过滤
CREATE INDEX IF NOT EXISTS ix_trans_borrow_time
ON trans_borrow(borrow_time);
-- 借用:回查库存表取库位的 JOIN 键
CREATE INDEX IF NOT EXISTS ix_trans_borrow_source_stock
ON trans_borrow(source_table, stock_id);
-- 入库没有独立流水表,直接以库存表自身的入库/生产时间计时
CREATE INDEX IF NOT EXISTS ix_stock_buy_in_date
ON stock_buy(in_date);
CREATE INDEX IF NOT EXISTS ix_stock_semi_production_date
ON stock_semi(production_date);
CREATE INDEX IF NOT EXISTS ix_stock_product_production_date
ON stock_product(production_date);
COMMIT;