PostgreSQL物化视图详解

news/2024/11/19 14:51:29/

物化视图简介

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

产生背景

随着数据库规模的增大和查询复杂性的提高,数据库查询的性能问题变得越来越突出。为了优化查询性能,数据库系统引入了物化视图(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.ppmy.cn/news/1548258.html

相关文章

ubuntu24.04设置开机自启动Eureka

ubuntu24.04设置开机自启动Eureka 之前我们是在/root/.bashrc的文件中增加了一条命令 nohup java -jar /usr/software/eurekaServer-auth-prd-03.jar > /usr/software/log.log 2>&1 &但上面这条命令只有在登录root的用户时,才会执行,如果…

React Native 全栈开发实战班 - 性能与调试之打包与发布

在完成 React Native 应用的开发与性能优化后,下一步就是将应用打包并发布到各大应用市场,如 Apple App Store 和 Google Play Store。本章节将详细介绍 React Native 应用的打包与发布流程,包括 Android 和 iOS 平台的打包步骤、签名配置、发…

NLP论文速读(多伦多大学)|利用人类偏好校准来调整机器翻译的元指标

论文速读|MetaMetrics-MT: Tuning Meta-Metrics for Machine Translation via Human Preference Calibration 论文信息: 简介: 本文的背景是机器翻译(MT)任务的评估。在机器翻译领域,由于不同场景和语言对的需求差异&a…

运维面试题.云计算面试题集锦第一套

运维+网络安全学科基础升就业 测试题(总分100分) 一,单词翻译(10分,直接写在答题卡上) 二,单选题(每题2分,共30题): 1.如下哪个属于管道符?( ) A、|| B、<< C、// D、| 2.有一备份程序mybackup,需要在周一至周五下午1点和晚上8点各运行一次,下面哪条cront…

23.<Spring图书管理系统(强制登录版本)>

在前面两篇&#xff0c;我们基本上实现了图书管理系统所有的功能&#xff0c;但是我们发现没有登录也能对其进行修改。这是非常不安全的。因此这篇文章我们学习如何进行强制登录。只有登录进去才能进行操作。 这不是一个对外开放的项目 这篇文章我们将改写图书管理系统为强制登…

Datawhale组队学习】模型减肥秘籍:模型压缩技术3——模型量化

模型量化的目的是通过将浮点运算转换为定点运算&#xff0c;以减少模型大小、内存和存储需求&#xff0c;同时加快推理速度&#xff0c;降低计算功耗&#xff0c;使得模型在低算力设备上运行更加高效&#xff0c;特别适用于嵌入式设备或移动端场景。 不同数据类型&#xff08;…

【金融风控】样本不均衡和异常点检测

内容介绍 知道样本不均衡时的常用处理方式 掌握SMOTE过采样的使用 掌握IForest算法的使用 【掌握】样本不均衡简介 通常分类机器学习任务期望每种类别的样本是均衡的&#xff0c;即不同目标值样本的总量接近相同。 在梯度下降过程中&#xff0c;不同类别的样本量有较大差异时…

Ascend C算子性能优化实用技巧05——API使用优化

Ascend C是CANN针对算子开发场景推出的编程语言&#xff0c;原生支持C和C标准规范&#xff0c;兼具开发效率和运行性能。使用Ascend C&#xff0c;开发者可以基于昇腾AI硬件&#xff0c;高效的实现自定义的创新算法。 目前已经有越来越多的开发者使用Ascend C&#xff0c;我们…