PostgreSQL物化视图详解

物化视图简介

物化视图的产生背景与概念

产生背景

随着数据库规模的增大和查询复杂性的提高,数据库查询的性能问题变得越来越突出。为了优化查询性能,数据库系统引入了物化视图(Materialized View)的概念。物化视图是一种预先计算和存储的查询结果,它可以在需要时直接提供查询结果,而无需重新执行复杂的查询操作。

概念

物化视图是预先计算和存储的查询结果,它以物理形式存储在数据库中。当需要执行相应的查询时,可以直接从物化视图中获取结果,从而避免了每次查询时都需要重新执行查询操作。

对比普通视图与物化视图

普通视图

普通视图是基于SQL语句的虚拟表,它并不存储实际的数据,而是根据SQL语句的结果动态生成。当查询普通视图时,系统会动态执行SQL语句并返回结果。

物化视图

与普通视图不同,物化视图是预先计算和存储的查询结果。它存储了实际的数据,而不是基于SQL语句的虚拟表。当查询物化视图时,系统可以直接从物化视图中获取结果,而无需重新执行查询操作。

物化视图的特点与优势

特点:

  • 预先计算和存储查询结果

  • 无需每次查询时重新执行查询操作

  • 可以提高查询性能

  • 减少了数据库负载

优势:

  • 提高查询性能:由于物化视图预先计算和存储了查询结果,所以查询时无需重新执行复杂的查询操作,从而提高了查询性能。

  • 减少数据库负载:通过预先计算和存储查询结果,减少了数据库查询的负载,提高了数据库系统的响应速度。

  • 简化数据处理流程:对于复杂和频繁的查询,物化视图可以简化数据处理流程,提高开发效率。

在实际应用中,根据具体的查询需求和数据库情况,可以合理选择使用普通视图或物化视图,以达到优化查询性能、简化数据处理流程的目的。

物化视图的创建与使用

创建物化视图的语法及示例

在PostgreSQL中,可以使用CREATE MATERIALIZED VIEW语句来创建物化视图。
创建物化视图语法:

postgres=# \h create materialized view
Command:     CREATE MATERIALIZED VIEW
Description: define a new materialized view
Syntax:
CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] table_name[ (column_name [, ...] ) ][ USING method ][ WITH ( storage_parameter [= value] [, ... ] ) ][ TABLESPACE tablespace_name ]AS query[ WITH [ NO ] DATA ]URL: https://www.postgresql.org/docs/15/sql-creatematerializedview.html

语法简介:

  • CREATE MATERIALIZED VIEW:这是用来创建物化视图的命令。

  • IF NOT EXISTS:这是一个可选的参数,如果指定的物化视图已经存在,则不会创建新的物化视图。

  • table_name:这是新的物化视图的名称。

  • column_name [, ...]:这是可选的,用于指定物化视图中的列名。如果省略,物化视图将包含查询中所有非聚合的列。

  • USING method:这是可选的,用于指定如何创建物化视图。PostgreSQL 目前只支持默认的方法,即简单的排序和哈希方法。

  • WITH ( storage_parameter [= value] [, ... ] ):这是可选的,用于指定物化视图的存储参数。例如,可以设置 FILLFACTOR 来控制物化视图的填充因子。

  • TABLESPACE tablespace_name:这是可选的,用于指定物化视图应该存储在哪个表空间。

  • AS query:这是必须的,表示物化视图是基于哪个查询的结果。

  • WITH [ NO ] DATA:这个参数决定了物化视图是否包含数据。默认情况下,物化视图包含数据。使用 NO DATA 可以创建一个不包含数据的物化视图。不论物化视图是否包含数据,不能直接对其执行插入、更新或删除操作(除非你使用了特殊的扩展或技巧)。物化视图的设计初衷是为了存储查询结果的快照,并不是作为一个可更新的数据表来使用的

示例:基于现有表创建物化视图

--创建表
CREATE TABLE test_view (id INT PRIMARY KEY,name VARCHAR(255),age INT
);--插入100万随机数据
INSERT INTO test_view (id, name, age)
SELECT generate_series(1, 1000000) AS id,md5(random()::text) AS name,floor(random() * 100) + 1 AS age;--创建物化视图
CREATE MATERIALIZED VIEW sample_view
AS
SELECT id, name, age
FROM test_view;

查看一下物化视图的信息:

--查看物化视图表的大小
postgres=# select pg_size_pretty(pg_relation_size('sample_view'));pg_size_pretty
----------------73 MB
(1 row)--查看查询计划,普通视图会扫描主表,而不是视图
postgres=# explain select * from sample_view;QUERY PLAN
----------------------------------------------------------------------Seq Scan on sample_view  (cost=0.00..19346.00 rows=1000000 width=41)
(1 row)

物化视图的查询

与普通表查询方式一致:物化视图一旦被创建,就可以像普通表一样进行查询操作。可以使用标准的SQL查询语句从物化视图中获取数据。

postgres=# select count(*) from sample_view;count
---------1000000
(1 row)postgres=# select * from sample_view limit 20;id |               name               | age
----+----------------------------------+-----1 | 5800a16f6d4914641b617f85f3bdc0e2 |  562 | 08465e0b3fce6ae0678ec40f8ae6cb1b |   43 | f1492a61186521ee6dc04dfa6378d7fe |  224 | df7bd8017d532e9751c2eca389ed8417 |  905 | 094b164a954ef14ce3fbc14a984666f6 |  926 | 2e8e8e677de432bdfbb6fc7ab1e13d6f |  407 | 4f54d050aafe688491804898ffb08065 |   28 | 2c5a35fb2916855564bff9b25cd00399 |  609 | c37a50ee642cdd47bce9cf2fcfdb696a |  8410 | a3f4d1f6dea3ccac5b9c9c3d7ee93cbf |  3611 | c5cdf694c6312e3fce547089d71833ed |  7212 | bdc969df554a63e3dc24137ba8296b7f |  2913 | 0dc92101c26acfacbed18c35684c03f6 |  2514 | ac95beb99bc53dffbabd3fb64d3fc85a |  7015 | 1b456d53e431d13216b58e1fd3fd5f12 |  2416 | bcd46c5422120b4105b931d337411648 |  2517 | 2209ed1bb20103cc70b418904049a9b9 |  2518 | 8daf526318066f6b1e58bee8298ab704 |  6519 | 23bd81ed6043632e7b399cfcff5d60e2 |  2220 | 5193d45eaa62f72c5df11005fcdbf87a |  87
(20 rows)

为物化视图创建索引

提升查询性能的方法:为了提高物化视图的查询性能,可以为其创建索引。索引可以加速对物化视图的查询操作,减少查询时间。

创建索引的语法及示例:

示例:为物化视图创建索引

CREATE INDEX index_view ON sample_view(id);

在这个示例中,index_view 是索引的名称,sample_view是物化视图的名称,id是想要为其创建索引的列的名称。创建索引后,查询操作会更快,因为查询优化器可以利用索引来加速查询过程。

需要注意的是,为物化视图创建索引的语法和为普通表创建索引的语法类似,但应用于物化视图时,需要确保在创建物化视图时,数据已经填充到物化视图中,然后再创建索引。

物化视图的维护

在PostgreSQL中,物化视图(Materialized View)是一种特殊的数据库对象,它存储了查询结果的快照。由于物化视图保存了实际的数据,因此它们需要定期刷新以保持与基础数据的一致性。

全量更新与增量更新的概念:

全量更新:指完全重新计算物化视图的内容,使用REFRESH MATERIALIZED VIEW语句。这通常涉及执行物化视图定义中的查询,并用新结果替换旧数据。全量更新可以确保数据的一致性,但可能消耗较多的时间和资源。

增量更新:指仅更新物化视图中发生变化的部分。这通常要求跟踪基础数据中的更改,并相应地更新物化视图。增量更新是一种优化策略,它专注于更新物化视图中那些实际发生变化的数据部分,而非整体重新计算。此策略要求系统能够追踪基础数据源中的更改,并将这些更改精确地映射到物化视图上。尽管增量更新能显著提升处理效率,特别是在大型数据集和频繁更新的场景下,但其实现过程相对复杂。值得注意的是,PostgreSQL的标准功能并未直接提供对物化视图增量更新的支持。因此,要实现增量更新,通常需要借助额外的工具或开发自定义的解决方案来应对这种复杂性。

使用REFRESH MATERIALIZED VIEW语句:

在PostgreSQL中,可以使用REFRESH MATERIALIZED VIEW语句来刷新物化视图。例如:

REFRESH MATERIALIZED VIEW sample_view;

具体操作示例

--test_view再添加1000000数据
postgres=# insert into test_view(id,name,age) select generate_series(1000001,2000000) as id,md5(random()::text) as name,floor(random()*100)+1 as age;
INSERT 0 1000000--查看test_view表数据量
postgres=# select count(*) from test_view;count
---------2000000
(1 row)--查看物化视图数据量
postgres=# select count(*) from sample_view;count
---------1000000
(1 row)--刷新物化视图数据量
postgres=# refresh MATERIALIZED VIEW sample_view;
REFRESH MATERIALIZED VIEW--查看刷新后物化视图数据量
postgres=# select count(*) from sample_view;count
---------2000000
(1 row)

这种方式刷新物化视图的时候会阻塞查询等操作,如果希望并发地刷新物化视图以减少对读取操作的影响,可以使用:

REFRESH MATERIALIZED VIEW CONCURRENTLY sample_view;

CONCURRENTLY 需要物化视图有一个唯一索引,否则会报错。

物化视图的分区

分区的概念与优势:

分区是一种将大型表或物化视图拆分为较小、更易于管理的部分的技术。每个分区可以独立于其他分区进行存储、备份和索引。分区可以提高查询性能、维护效率和数据管理灵活性。

如何实现物化视图的分区:

在PostgreSQL中,表分区是一种将数据分成多个较小的、更易于管理的片段(称为分区)的技术,这些片段在物理上是分离的,但在逻辑上仍然作为单个表来处理。虽然PostgreSQL不直接支持物化视图的分区,但可以通过创建一个分区表,并基于该分区表定义物化视图,从而间接地实现类似的效果。

以下是一个简单的示例:

创建分区表:
首先,创建一个分区表。在这个例子中,我们将创建一个按月分区的销售表。

CREATE TABLE test_sales (sale_id INT,sale_date DATE NOT NULL,amount NUMERIC(10, 2) NOT NULL,PRIMARY KEY(sale_id,sale_date)
) PARTITION BY RANGE (sale_date);

创建分区,例如为2023年的每个月创建一个分区

CREATE TABLE sales_202301 PARTITION OF test_sales FOR VALUES FROM ('2023-01-01') TO ('2023-02-01');
CREATE TABLE sales_202302 PARTITION OF test_sales FOR VALUES FROM ('2023-02-01') TO ('2023-03-01');
-- ... 为其他月份创建分区 ...

创建基于分区表的物化视图:
创建一个物化视图,该视图基于上面创建的分区表。这个物化视图将包含一些聚合数据,例如每个月的总销售额。

CREATE MATERIALIZED VIEW monthly_sales_mv AS
SELECT DATE_TRUNC('month', sale_date) AS month,SUM(amount) AS total_sales
FROM test_sales 
GROUP BY month;

刷新物化视图:

当基础数据发生变化时,你需要刷新物化视图以更新其内容。由于这是基于分区表的物化视图,刷新操作将考虑所有分区中的数据。

REFRESH MATERIALIZED VIEW monthly_sales_mv;

请注意,尽管物化视图monthly_sales_mv是基于分区表test_sales创建的,但它本身并不是一个分区表。这意味着物化视图中的数据不会自动按分区存储。然而,由于物化视图的定义是基于分区表的,因此在刷新物化视图时,PostgreSQL将利用分区表的优势来优化查询性能。

此外,虽然这种方法可以利用分区表的性能优势,但它并不提供物化视图的增量更新功能。每次刷新物化视图时,仍然会重新计算整个视图的内容。如果你需要更细粒度的更新策略,可能需要考虑其他方法或工具来实现增量更新。

四、物化视图的应用场景

性能优化

物化视图特别适合用于优化复杂且频繁执行的查询。通过将查询结果存储为物化视图,可以避免重复执行相同的计算密集型查询,从而提高性能。

数据聚合与预处理:

物化视图还可以用于数据聚合和预处理。例如,可以创建一个物化视图来汇总销售数据,以便更快地生成报告或进行数据分析。这可以简化数据处理流程并提高分析效率。

五、注意事项与最佳实践

物化视图的更新频率与数据实时性权衡:

在选择物化视图的更新频率时,需要权衡数据实时性和系统性能。过于频繁的更新可能会消耗大量资源,而更新不足则可能导致数据过时。

选择合适的存储与索引策略:

为了提高物化视图的性能,应选择合适的存储参数和索引策略。例如,可以使用适当的压缩选项来减少存储空间的使用,并为物化视图创建必要的索引以加速查询。

监控与调优物化视图的性能:

定期监控物化视图的性能并根据需要进行调优。这包括检查查询执行计划、分析物化视图的访问模式以及调整相关的配置参数。

PostgreSQL物化视图是一种强大的工具,它可以提高查询性能、简化数据处理并优化数据仓库和数据集成等场景的操作。然而,在使用物化视图时,我们也需要注意其数据更新的限制和维护的成本

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60681.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

球差控制操作数【ZEMAX操作数】

在光学设计中,对于球差的控制是必要的,那么在zemax中如何控制球差的大小,理解球差,以及使用相应操作数控制球差; 在这篇中主要写如何使用zemax操作数去控制或者消除球差,对球差进行简单的描述,之…

学习threejs,使用TWEEN插件实现动画

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.PLYLoader PLY模型加…

前端 JS 实用操作总结

目录 1、重构解构 1、数组解构 2、对象解构 3、...展开 2、箭头函数 1、简写 2、this指向 3、没有arguments 4、普通函数this的指向 3、数组实用方法 1、map和filter 2、find 3、reduce 1、重构解构 1、数组解构 const arr ["唐僧", "孙悟空&quo…

从0开始学习--Day26--聚类算法

无监督学习(Unsupervised learning and introduction) 监督学习问题的样本 无监督学习样本 如图,可以看到两者的区别在于无监督学习的样本是没有标签的,换言之就是无监督学习不会赋予主观上的判断,需要算法自己去探寻区别,第二张…

矩阵数组转置

#include<stdio.h> int main() {int arr1[3][4];//三行四列变成四行三列int arr2[4][3];for(int i0;i<3;i)//三行{for(int j0;j<4;j)//四列{scanf("%d",&arr1[i][j]);//录入}}for(int i0;i<3;i)//转置{for(int j0;j<4;j){arr2[j][i]arr1[i][j]…

利用正则表达式批量修改文件名

首先&#xff0c; 我们需要稍微学习一下正则表达式的使用方式&#xff0c;可以看这里&#xff1a;Notepad正则表达式使用方法_notepad正则匹配-CSDN博客 经过初步学习之后&#xff0c;比较重要的内容我做如下转载&#xff1a; 元字符是正则表达式的基本构成单位&#xff0c;它们…

rust高级特征

文章目录 不安全的rust解引用裸指针裸指针与引用和智能指针的区别裸指针使用解引用运算符 *&#xff0c;这需要一个 unsafe 块调用不安全函数或方法在不安全的代码之上构建一个安全的抽象层 使用 extern 函数调用外部代码rust调用C语言函数rust接口被C语言程序调用 访问或修改可…

【How AI Works】读书笔记3 出发吧! AI纵览 第二部分

目录 1.说明 2.第二部分(P9~P10) 机器学习算法总结(监督学习) 3.单词 4.专业术语 1.说明 书全名:How AI Works From Sorcery to Science 作者 Ronald T.Kneusel 2.第二部分(P9~P10) 总结机器学习算法 作者把机器学习的过程比喻成输入-->黑盒-->输出 这里的标签可…

HarmonyOS NEXT应用开发实战 ( 应用的签名、打包上架,各种证书详解)

前言 没经历过的童鞋&#xff0c;首次对HarmonyOS的应用签名打包上架可能感觉繁琐。需要各种秘钥证书生成和申请&#xff0c;混在一起也分不清。其实搞清楚后也就那会事&#xff0c;各个文件都有它存在的作用。 HarmonyOS通过数字证书与Profile文件等签名信息来保证鸿蒙应用/…

【自用】0-1背包问题与完全背包问题的Java实现

引言 背包问题是计算机科学领域的一个经典优化问题&#xff0c;分为多种类型&#xff0c;其中最常见的是0-1背包问题和完全背包问题。这两种问题的核心在于如何在有限的空间内最大化收益&#xff0c;但它们之间存在一些关键的区别&#xff1a;0-1背包问题允许每个物品只能选择…

Python_爬虫3_Requests库网络爬虫实战(5个实例)

目录 实例1&#xff1a;京东商品页面的爬取 实例2&#xff1a;亚马逊商品页面的爬取 实例3&#xff1a;百度360搜索关键词提交 实例4&#xff1a;网络图片的爬取和存储 实例5&#xff1a;IP地址归地的自动查询 实例1&#xff1a;京东商品页面的爬取 import requests url …

黑马微项目

目录 1 飞机票 2 生成一个五位数验证码 3 数字加密 4 数字解密 5 抢红包 6 双色球系统 7 用户登录 8 金额转换 9 手机号屏蔽 10 罗马数字转换 11 调整字符串 12 初级学生管理系统&#xff08;学生数据的管理&#xff09; 13 学生管理系统&#xff08;用户的相关操…

C2M柔性制造模式

C2M柔性制造模式&#xff08;Customer-to-Manufacturer&#xff0c;客户到制造商的柔性制造模式&#xff09;是一种新型的生产模式&#xff0c;强调客户需求与制造过程的直接对接&#xff0c;并且能够快速响应和适应客户个性化的定制需求。这种模式结合了定制化生产与智能制造&…

IoT [remote electricity meter]

IoT [remote electricity meter] 物联网&#xff0c;远程抄表&#xff0c;电表数据&#xff0c;举个例子

2、开发工具和环境搭建

万丈高楼平地起&#xff0c;学习C语言先从安装个软件工具开始吧。 1、C语言软件工具有两个作用 1、编辑器 -- 写代码的工具 2、编译器 -- 将代码翻译成机器代码0和1 接下来我们介绍两种C语言代码工具&#xff1a;devcpp 和 VS2019&#xff0c;大家可以根据自己的喜好安装。 dev…

20241115在飞凌的OK3588-C的核心板上跑Linux R4时拿大文件到电脑的方法

20241115在飞凌的OK3588-C的核心板上跑Linux R4时拿大文件到电脑的方法 2024/11/15 15:26 缘起&#xff1a;使用SONY 405的机芯&#xff0c;以1080p60录像了半小时&#xff0c;3.5GB的mp4视频要拿到电脑上播放确认。 方法&#xff1a;1、拷贝到TF卡。记住&#xff0c;对于FAT32…

MySQL一些使用操作-持续更新

MySQL相关操作 1.MySQL不删除数据的情况下&#xff0c;让自增id重新排序 应用场景&#xff1a;Mysql&#xff08;当你删除表中数据之后&#xff0c;造成自增id不连续&#xff0c;可能会导致需要用id进行的判断的时候不准确&#xff0c;所以我想到了要重新排序&#xff0c;当然…

async 和 await的使用

一、需求 点击按钮处理重复提交&#xff0c;想要通过disabled的方式实现。 但是点击按钮调用的方法里有ajax、跳转、弹窗等一系列逻辑操作&#xff0c;需要等方法里流程都走完&#xff0c;再把disabled设为false&#xff0c;这样下次点击按钮时就可以继续走方法里的ajax等操作…

解决 idea windows 设置maven离线模式之后,maven继续请求远程仓库

在内网开发的时候经常遇到没有办法来链接远程仓库的情况&#xff0c;这个时候需要设置maven的离线模式。 idea windows 设置maven离线模式之后&#xff0c;maven继续请求远程仓库 当设置完离线模式之后&#xff0c;有的时候执行maven的命令会报错&#xff0c;提示请求远程失败…

StructuredStreaming (一)

一、sparkStreaming的不足 1.基于微批,延迟高不能做到真正的实时 2.DStream基于RDD,不直接支持SQL 3.流批处理的API应用层不统一,(流用的DStream-底层是RDD,批用的DF/DS/RDD) 4.不支持EventTime事件时间&#xff08;一般流处理都会有两个时间&#xff1a;事件发生的事件&am…