我正在將一堆數據加載到Postgresql 9.3數據庫中,然後我想刷新所有依賴於更新表的物化視圖。有沒有辦法自動執行它,而不是通過每個視圖並逐一刷新它們?我知道Oracle可以很容易地做到這一點,但在梳理PostgreSQL文檔後我沒有發現任何東西。如何一次刷新Postgresql 9.3中的所有物化視圖?
8
A
回答
18
看起來像當前版本的PostgreSQL(9.3.1)不具有這樣的功能,不得不寫我自己的函數:
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public')
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg;
FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg
LOOP
RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname;
END LOOP;
RETURN 1;
END
$$ LANGUAGE plpgsql;
(在GitHub上:https://github.com/sorokine/RefreshAllMaterializedViews)
1
同樣的方法,添加待機檢查
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public')
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg;
if pg_is_in_recovery() then
return 1;
else
FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg
LOOP
RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname;
END LOOP;
end if;
RETURN 1;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(schema_arg TEXT DEFAULT 'public')
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view in schema %', schema_arg;
if pg_is_in_recovery() then
return 1;
else
FOR r IN SELECT matviewname FROM pg_matviews WHERE schemaname = schema_arg
LOOP
RAISE NOTICE 'Refreshing %.%', schema_arg, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || schema_arg || '.' || r.matviewname;
END LOOP;
end if;
RETURN 1;
END
$$ LANGUAGE plpgsql;
2
相同的方法,添加了在所有架構上運行它的選項,可以同時運行。
CREATE OR REPLACE FUNCTION RefreshAllMaterializedViews(_schema TEXT DEFAULT '*', _concurrently BOOLEAN DEFAULT false)
RETURNS INT AS $$
DECLARE
r RECORD;
BEGIN
RAISE NOTICE 'Refreshing materialized view(s) in % %', CASE WHEN _schema = '*' THEN ' all schemas' ELSE 'schema "'|| _schema || '"' END, CASE WHEN _concurrently THEN 'concurrently' ELSE '' END;
IF pg_is_in_recovery() THEN
RETURN 0;
ELSE
FOR r IN SELECT schemaname, matviewname FROM pg_matviews WHERE schemaname = _schema OR _schema = '*'
LOOP
RAISE NOTICE 'Refreshing %.%', r.schemaname, r.matviewname;
EXECUTE 'REFRESH MATERIALIZED VIEW ' || CASE WHEN _concurrently THEN 'CONCURRENTLY ' ELSE '' END || '"' || r.schemaname || '"."' || r.matviewname || '"';
END LOOP;
END IF;
RETURN 1;
END
$$ LANGUAGE plpgsql;
我也把它在GitHub上:https://github.com/frankhommers/RefreshAllMaterializedViews
1
的片段下方使用REFRESH MATERIALIZED VIEW CONCURRENTLY
當UNIQUE
指數存在這一觀點。
CREATE OR REPLACE FUNCTION public.refresh_materialized_views()
RETURNS void
AS
$BODY$
DECLARE
refresh_sql text;
BEGIN
WITH matviews AS (
SELECT t.oid,
relname AS view_name,
nspname AS schema_name
FROM pg_class t
JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
WHERE t.relkind = 'm'
AND nspname NOT LIKE 'pg-%'
), unique_indexes AS (
SELECT m.oid,
view_name,
schema_name
FROM pg_class i,
pg_index ix,
matviews m
WHERE ix.indisunique = true
AND ix.indexrelid = i.oid
AND ix.indrelid = m.oid
), refresh_concurrently AS (
SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM unique_indexes
), refresh AS (
SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM matviews
WHERE oid != all (SELECT oid FROM unique_indexes)
), sql AS (
SELECT sql FROM refresh_concurrently
UNION ALL
SELECT sql FROM refresh
)
SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
EXECUTE refresh_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
此代碼段接受模式名稱以限制刷新的視圖。
CREATE OR REPLACE FUNCTION public.refresh_materialized_views(_schema text)
RETURNS void
AS
$BODY$
DECLARE
refresh_sql text;
BEGIN
WITH matviews AS (
SELECT t.oid,
relname AS view_name,
nspname AS schema_name
FROM pg_class t
JOIN pg_catalog.pg_namespace n ON n.oid = t.relnamespace
WHERE t.relkind = 'm'
AND nspname NOT LIKE 'pg-%'
AND nspname = _schema
), unique_indexes AS (
SELECT m.oid,
view_name,
schema_name
FROM pg_class i,
pg_index ix,
matviews m
WHERE ix.indisunique = true
AND ix.indexrelid = i.oid
AND ix.indrelid = m.oid
), refresh_concurrently AS (
SELECT 'REFRESH MATERIALIZED VIEW CONCURRENTLY ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM unique_indexes
), refresh AS (
SELECT 'REFRESH MATERIALIZED VIEW ' || quote_ident(schema_name) || '.' || quote_ident(view_name) AS sql
FROM matviews
WHERE oid != all (SELECT oid FROM unique_indexes)
), sql AS (
SELECT sql FROM refresh_concurrently
UNION ALL
SELECT sql FROM refresh
)
SELECT string_agg(sql, E';\n') || E';\n' FROM sql INTO refresh_sql;
EXECUTE refresh_sql;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
相關問題
- 1. PostgreSQL物化視圖刷新「堆棧」
- 2. 物化視圖 - 識別上次刷新
- 3. Dokku + Postgres:如何刷新物化視圖?
- 4. Postgres如何刷新物化視圖?
- 5. 如何刷新在Oracle物化視圖
- 6. 在PostgreSQL 9.3中編輯物化視圖(如果其他視圖依賴於它)
- 7. 刷新物化視圖
- 8. 物化視圖不刷新
- 9. pgsql物化視圖刷新
- 10. 是否可以部分刷新PostgreSQL中的物化視圖?
- 11. 刷新現有物化視圖
- 12. 每個物化視圖的下一次刷新時間信息
- 13. 創建每隔5分鐘刷新一次的物化視圖
- 14. PostgreSQL物化視圖
- 15. PostgreSQL的物化視圖是由自身刷新
- 16. 我們如何處理僅在物化視圖中上次刷新的數據
- 17. Oracle禁用物化視圖刷新
- 18. 物化視圖刷新從Informatica
- 19. 獲取Oracle物化視圖以刷新
- 20. 歷史刷新物化視圖
- 21. 物化視圖刷新致力
- 22. 物化視圖停止刷新
- 23. oracle物化視圖刷新時間
- 24. 物化視圖中的完全刷新和快速刷新有什麼區別?
- 25. 如何刷新每個工作日的物化視圖?
- 26. 基於非快速刷新視圖的快速刷新物化視圖
- 27. 刷新具有併發性的物化視圖
- 28. 具有20億數據的物化視圖刷新
- 29. 如何使用activejdbc刷新物化視圖?
- 30. 如何防止物化視圖在pg_restore期間刷新?
檢查pg_matviews,選擇您需要的所有視圖並進行刷新。你可以爲此寫一個函數。 –
看起來像寫我自己的功能是唯一的選擇與當前版本 – srk