122290e3b0
新增物化视图: - mv_store_action_priority_deep_monthly (10.7s→3ms) - mv_inventory_cost_classified_monthly (37ms→3ms, 消除重复调用) - mv_dish_pair_summary_monthly (171s→3ms) - mv_store_area_efficiency_monthly (10.1s→3ms) - mv_store_site_profile_monthly (9.3s→3ms) - mv_site_segment_benchmark_monthly (12s→3ms) - mv_store_site_replication_monthly (12.6s→3ms) - mv_store_overlap_risk_monthly (88s→3ms) - mv_district_site_benchmark_monthly (56s→3ms) 后端: 所有 fn_ 函数调用替换为物化视图查询 前端: BossPage 添加 MonthPicker 组件并传递 month 参数 修复: cost/category-benchmark 排序列名 store_code→sales_store_code 总计: 21个物化视图, 全部API响应<1.7秒
85 lines
4.5 KiB
PL/PgSQL
85 lines
4.5 KiB
PL/PgSQL
-- ============================================================
|
|
-- Phase 12: 物化剩余慢函数(耗时较长的选址和搭配分析)
|
|
-- 执行: psql -d bill_query -f db/migration_phase12_materialize_rest.sql
|
|
-- ============================================================
|
|
|
|
-- 6. mv_store_site_replication_monthly (12.6s)
|
|
DROP MATERIALIZED VIEW IF EXISTS analytics.mv_store_site_replication_monthly;
|
|
CREATE MATERIALIZED VIEW analytics.mv_store_site_replication_monthly AS
|
|
SELECT m.month_start::date AS month_start, r.*
|
|
FROM generate_series(
|
|
(SELECT date_trunc('month', min(closed_at))::date FROM analytics.bill_fact),
|
|
(SELECT date_trunc('month', max(closed_at))::date FROM analytics.bill_fact),
|
|
interval '1 month'
|
|
) AS m(month_start)
|
|
CROSS JOIN LATERAL analytics.fn_store_site_replication(m.month_start::date) r;
|
|
CREATE UNIQUE INDEX idx_mv_site_repl_month_store ON analytics.mv_store_site_replication_monthly (month_start, store_code);
|
|
CREATE INDEX idx_mv_site_repl_month ON analytics.mv_store_site_replication_monthly (month_start);
|
|
|
|
-- 7. mv_store_overlap_risk_monthly (88s)
|
|
DROP MATERIALIZED VIEW IF EXISTS analytics.mv_store_overlap_risk_monthly;
|
|
CREATE MATERIALIZED VIEW analytics.mv_store_overlap_risk_monthly AS
|
|
SELECT m.month_start::date AS month_start, r.*
|
|
FROM generate_series(
|
|
(SELECT date_trunc('month', min(closed_at))::date FROM analytics.bill_fact),
|
|
(SELECT date_trunc('month', max(closed_at))::date FROM analytics.bill_fact),
|
|
interval '1 month'
|
|
) AS m(month_start)
|
|
CROSS JOIN LATERAL analytics.fn_store_overlap_risk(m.month_start::date) r;
|
|
CREATE INDEX idx_mv_overlap_risk_month ON analytics.mv_store_overlap_risk_monthly (month_start);
|
|
|
|
-- 8. mv_district_site_benchmark_monthly (56s)
|
|
DROP MATERIALIZED VIEW IF EXISTS analytics.mv_district_site_benchmark_monthly;
|
|
CREATE MATERIALIZED VIEW analytics.mv_district_site_benchmark_monthly AS
|
|
SELECT m.month_start::date AS month_start, r.*
|
|
FROM generate_series(
|
|
(SELECT date_trunc('month', min(closed_at))::date FROM analytics.bill_fact),
|
|
(SELECT date_trunc('month', max(closed_at))::date FROM analytics.bill_fact),
|
|
interval '1 month'
|
|
) AS m(month_start)
|
|
CROSS JOIN LATERAL analytics.fn_district_site_benchmark(m.month_start::date) r;
|
|
CREATE INDEX idx_mv_district_bench_month ON analytics.mv_district_site_benchmark_monthly (month_start);
|
|
|
|
-- 9. mv_dish_pair_summary_monthly (171s!! the slowest)
|
|
DROP MATERIALIZED VIEW IF EXISTS analytics.mv_dish_pair_summary_monthly;
|
|
CREATE MATERIALIZED VIEW analytics.mv_dish_pair_summary_monthly AS
|
|
SELECT m.month_start::date AS month_start, r.*
|
|
FROM generate_series(
|
|
(SELECT date_trunc('month', min(closed_at))::date FROM analytics.bill_fact),
|
|
(SELECT date_trunc('month', max(closed_at))::date FROM analytics.bill_fact),
|
|
interval '1 month'
|
|
) AS m(month_start)
|
|
CROSS JOIN LATERAL analytics.fn_dish_pair_summary(m.month_start::date) r;
|
|
CREATE INDEX idx_mv_dish_pair_month ON analytics.mv_dish_pair_summary_monthly (month_start);
|
|
|
|
-- 更新刷新函数
|
|
CREATE OR REPLACE FUNCTION analytics.refresh_all_monthly_views()
|
|
RETURNS void
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
BEGIN
|
|
REFRESH MATERIALIZED VIEW analytics.mv_dish_sku_summary_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_dish_sku_abc_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_risk_rating_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_platform_economics_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_category_mix_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_member_opportunity_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_benchmark_composite_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_deep_diagnosis_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_dish_basket_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_dish_store_summary_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_theoretical_actual_cost_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_action_priority_deep_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_inventory_cost_classified_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_dish_pair_summary_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_area_efficiency_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_site_profile_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_site_segment_benchmark_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_site_replication_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_store_overlap_risk_monthly;
|
|
REFRESH MATERIALIZED VIEW analytics.mv_district_site_benchmark_monthly;
|
|
END;
|
|
$function$;
|
|
|
|
SELECT 'Phase 12 complete' AS status;
|