如何为多表关联查询创建带触发器函数自动刷新的MATERIALIZED VIEW
表结构定义
现有4张业务数据表,DDL如下:
CREATE TABLE public.type ( id serial, name text, groups_id integer, comment text ); CREATE TABLE public.berand ( id serial, name text, type_id integer, comment text ); CREATE TABLE public.model ( id serial, name text, berand_id integer, comment text ); CREATE TABLE public.versions ( id serial, name text, model_id integer, comment text );
慢查询问题
多层左关联查询性能较差,对应查询语句如下:
SELECT id,name tname, bname, mname, vname FROM type left join( select berand.type_id, berand.name bname,mname,vname from berand left join ( select model.name mname, versions.name vname,model.berand_id from model left join versions on versions.model_id = model.id ) m on berand.id = m.berand_id ) b on b.type_id = type.id;
优化方案:物化视图+自动刷新实现
通过物化视图预计算关联结果,直接查询物化视图可大幅降低耗时,搭配触发器实现源表数据变更时自动刷新物化视图,完整实现代码如下:
-- 创建预关联结果物化视图 CREATE MATERIALIZED VIEW v_tbmv AS SELECT id,name tname, bname, mname, vname FROM type left join(select berand.type_id, berand.name bname,mname,vname from berand left join (select model.name mname, versions.name vname,model.berand_id from model left join versions on versions.model_id = model.id) m on berand.id = m.berand_id) b on b.type_id = type.id; -- 定义物化视图刷新函数 CREATE OR REPLACE FUNCTION fn_refresh_v_tbmv() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN REFRESH MATERIALIZED VIEW v_tbmv; RETURN NULL; END; $$; -- 为四张源表绑定数据变更触发规则 CREATE TRIGGER tg_refresh_v_tbmv_type AFTER INSERT OR UPDATE OR DELETE ON type FOR EACH STATEMENT EXECUTE PROCEDURE fn_refresh_v_tbmv(); CREATE TRIGGER tg_refresh_v_tbmv_berand AFTER INSERT OR UPDATE OR DELETE ON berand FOR EACH STATEMENT EXECUTE PROCEDURE fn_refresh_v_tbmv(); CREATE TRIGGER tg_refresh_v_tbmv_model AFTER INSERT OR UPDATE OR DELETE ON model FOR EACH STATEMENT EXECUTE PROCEDURE fn_refresh_v_tbmv(); CREATE TRIGGER tg_refresh_v_tbmv_versions AFTER INSERT OR UPDATE OR DELETE ON versions -- *原代码误将该触发器绑定到type表,此处已修正* FOR EACH STATEMENT EXECUTE PROCEDURE fn_refresh_v_tbmv();
补充提示:如果数据量较大、对刷新时效要求不高的场景,也可改为定时任务调度刷新,避免高频数据变更触发多次刷新影响写入性能。
内容的提问来源于stack exchange,提问作者yasdd dsfsdf
相关产品推荐
相关产品推荐

