跳至内容
SQL
数据工程

SQL 物化视图:提升查询性能

了解物化视图如何提升 SQL 数据库中的查询性能,并掌握不同数据库中物化视图的限制与最佳实践。
Allan Ouko's photo
Allan Ouko
已更新 · 9分钟 阅读

使用 AI 探索

ChatGPTClaudePerplexity

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。

物化视图是 SQL 数据库中的一项强大功能,通过将查询结果以物理形式存储在磁盘上,避免反复计算,从而加速查询性能。它们对涉及连接、聚合和大型数据集的复杂、资源密集型查询尤其有用。

在开始之前,建议您学习 DataCamp 的 Introduction to SQL 课程和 SQL Fundamentals 技能路径,掌握 SQL 基础以及如何通过查询提取数据。您还可以参考 SQL Basics Cheat Sheet,了解常用的 SQL 过滤与聚合函数。

什么是 SQL 物化视图?

物化视图是一种特殊的数据库对象,它将查询的结果以物理方式存储,而不是像常规视图那样在访问时即时计算。常规 SQL 视图是一个已保存的 SQL 查询,每次访问都会动态生成结果;而物化视图会预计算并将数据存储为类似表的结构。

通过将结果集存储到磁盘,物化视图可以显著降低数据库负载、提升查询性能,并有助于简化计算密集型操作的处理。

在 SQL 中创建物化视图

创建物化视图需要使用 CREATE MATERIALIZED VIEW 语法,不同 SQL 数据库的语法略有差异。以下展示在 SQL Server、PostgreSQL 和 Oracle 中创建物化视图的方法。

PostgreSQL 中的物化视图

在 PostgreSQL 中,您可以使用如下语法创建物化视图。此示例创建名为 sales_summary 的物化视图,用于汇总各产品的总销量与总收入。

-- Create a materialized view to summarize sales data
CREATE MATERIALIZED VIEW sales_summary AS
SELECT product_id, 
       SUM(quantity) AS total_quantity, 
       SUM(price * quantity) AS total_revenue
FROM sales
GROUP BY product_id;

SQL Server 中的物化视图

在 SQL Server 中,物化视图称为“索引视图”(Indexed Views)。要创建索引视图,底层表需满足特定要求,例如启用 WITH SCHEMABINDING 选项。

WITH SCHEMABINDING 选项可确保在索引视图存在期间架构不会变更。要将视图物化,必须为其创建唯一聚集索引。

-- Create an indexed view with schema binding to summarize sales data
CREATE VIEW sales_summary
WITH SCHEMABINDING 
AS
SELECT product_id, 
       COUNT_BIG(*) AS record_count,
       SUM(ISNULL(quantity, 0)) AS total_quantity,
       SUM(ISNULL(price, 0) * ISNULL(quantity, 0)) AS total_revenue
FROM sales
GROUP BY product_id;
GO
-- Create a unique clustered index to materialize the view
CREATE UNIQUE CLUSTERED INDEX IX_sales_summary 
ON sales_summary (product_id);
GO

如果您想进一步了解 SQL Server,建议查看我们的 SQL Server Fundamentals 技能路径,熟悉用于数据分析的多种 SQL 技能。

Oracle 中的物化视图

在 Oracle 中创建物化视图的语法与 PostgreSQL 类似。我们还可以指定刷新选项,例如 ON DEMAND 或 ON COMMIT。

-- Create a materialized view to summarize sales data
CREATE MATERIALIZED VIEW sales_summary
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
AS
SELECT product_id, SUM(quantity) AS total_quantity, SUM(price * quantity) AS total_revenue
FROM sales
GROUP BY product_id;

分布式数据库中的物化视图

在支持分布式数据仓库的数据库(如 Azure Synapse 或 Amazon Redshift)中,物化视图还可以指定分布方式以获得更好的性能。

Amazon Redshift 的哈希分布

下面的查询创建名为 sales_summary 的物化视图,按 product_id 汇总总销量与总收入。DISTSTYLE KEY 和 DISTKEY(product_id) 选项确保数据基于 product_id 在各节点间分布,从而提升在该列上进行连接查询时的性能。

-- Create a materialized view with key-based distribution for efficient joins
CREATE MATERIALIZED VIEW sales_summary
DISTSTYLE KEY
DISTKEY(product_id)
AS
SELECT product_id, 
       SUM(quantity) AS total_quantity, 
       SUM(price * quantity) AS total_revenue
FROM sales
GROUP BY product_id;

Azure Synapse 的轮询分布

此查询创建名为 sales_summary 的物化视图,按 product_id 汇总总销量与总收入。ROUND_ROBIN 分布会将数据平均分布到各节点,适用于不严重依赖连接的场景。

-- Create a materialized view with round-robin distribution for balanced data storage
CREATE MATERIALIZED VIEW sales_summary
WITH (DISTRIBUTION = ROUND_ROBIN)
AS
SELECT product_id, 
       SUM(quantity) AS total_quantity, 
       SUM(price * quantity) AS total_revenue
FROM sales
GROUP BY product_id;

在 SQL 中刷新物化视图

物化视图中的数据可以刷新,以与底层表保持同步。选择何种刷新方式取决于具体数据库的业务需求与性能考量。下面介绍物化视图的常见数据刷新方法。

手动刷新

手动刷新仅在用户明确发起时才会执行刷新。该方式能最大程度控制数据更新时机,适用于数据变更不频繁或在离峰时段进行更新的场景。

以下查询展示了在 PostgreSQL 中的手动刷新方法。

REFRESH MATERIALIZED VIEW sales_summary;

定期刷新

在指定的刷新周期内,物化视图会按预设间隔自动刷新,无需用户干预即可确保数据较为最新。此方法适用于对时效性有要求且需要保持数据相对实时的应用。

下面的示例展示了如何在 Oracle 中通过在 CREATE MATERIALIZED VIEW 语句中直接定义刷新计划来实现定期刷新。刷新时间设置为每小时一次。

-- Create a materialized view to aggregate sales data
-- Set to refresh completely every hour
CREATE MATERIALIZED VIEW sales_summary
REFRESH COMPLETE START WITH (SYSDATE) NEXT (SYSDATE + 1/24)
AS
SELECT product_id, 
       SUM(quantity) AS total_quantity, 
       SUM(price * quantity) AS total_revenue
FROM sales
GROUP BY product_id;

按需刷新

按需刷新在底层数据发生变化时触发,通常通过触发器机制实现。这样可以确保物化视图始终包含最新数据。例如,在 PostgreSQL 中,可以设置触发器在底层表发生变更时刷新视图。

完全刷新与增量刷新

在物化视图中可以选择完全刷新或增量刷新。下表总结了两种方法及其适用场景。

刷新类型 说明 优势 不足
完全刷新 重新加载整个数据集,替换视图中的所有现有数据 - 实现简单
- 重建整个视图
- 对大型数据集资源消耗大
- 刷新时间更长
增量刷新 仅更新视图中发生变化的部分 - 更高效,仅处理已修改数据
- 适用于频繁变更的大型数据集
- 需要额外配置(如用于跟踪变更的日志)
- 并非所有查询都支持

物化视图的最佳实践

使用物化视图时,请考虑以下实践以实现最佳效果。

  • 选择合适的查询进行物化:优先物化复杂且资源密集的查询,如连接、聚合和子查询。这类查询受益于预计算结果,可降低数据库负载。
  • 平衡数据新鲜度与性能:根据您的使用场景选择合适的刷新策略,如手动、定期或按需刷新。尽可能使用增量刷新以降低计算开销,并根据数据变更频率设置刷新间隔。
  • 用物化视图优化查询密集型工作负载:在需要快速响应的 BI 报表与仪表板中充分利用物化视图。您也可以为物化视图中使用的列建立索引,以加速过滤与排序。

不同数据库系统中的物化视图

如您所见,不同数据库系统对物化视图的支持程度各不相同。下表总结了这些数据库中物化视图的特色功能与限制。

数据库系统 刷新方式 增量刷新 自动刷新 特性/限制
PostgreSQL 手动(REFRESH MATERIALIZED VIEW) 否 否 缺乏原生增量刷新。需要手动调度。
SQL Server 自动(索引视图) 是(自动同步) 是

需要 WITH SCHEMABINDING。查询支持有限。

Oracle 手动、提交时、计划任务 是(快速刷新) 是 支持快速刷新、分区与并行。需要视图日志。
Amazon Redshift 手动、计划任务 是 是 支持使用哈希或轮询分布的分布式数据。
MySQL 无原生支持 否 否 需要替代方案(如临时表、第三方工具)。
Azure Synapse 手动、计划任务 是 是 可选择不同分布策略进行优化。

如果您常用 SQL Server,建议学习 DataCamp 的 Introduction to SQL Server 课程,掌握用于数据分析的 Microsoft SQL Server 基础;同时查看我们的 SQL Server Developer 职业路径,了解如何优化查询并排查 SQL Server 中的问题。

其他注意事项

尽管 SQL 物化视图有助于优化查询,它们也存在一些挑战与限制。以下是物化视图的常见问题及应对方法。

  • 存储开销:物化视图将查询结果以物理形式存储在磁盘上,会增加存储需求。为避免不必要的存储占用,仅对资源密集型查询进行物化,并对大型数据集的物化视图进行分区。
  • 更新成本与刷新开销:保持物化视图与底层表同步可能较为耗费资源,尤其当视图需要频繁更新或涉及复杂计算时。为降低刷新开销,在支持的情况下使用增量刷新,或在数据库负载较低的时段设置合适的刷新间隔。
  • 数据一致性与同步:如果底层数据频繁变化,物化视图可能会过期,导致数据陈旧。为避免此问题,应选择合适的刷新策略,并监控数据变更以按需调整刷新策略。
  • 维护开销:物化视图需要持续维护,例如设置合适的刷新计划、监控存储使用情况以及跟踪对底层表的依赖。为应对这一挑战,请使用自动化刷新计划、监控系统性能,并为刷新失败设置告警。

结论

在 SQL 数据库中,物化视图是优化查询性能的有力工具。它们将查询结果以物理形式存储,借助减少重复计算来加速查询。这使其非常适合处理涉及连接、聚合和大型数据集的复杂、资源密集型查询。了解如何在不同数据库中实现物化视图,将有助于提升您的查询与数据库优化能力。

如果您希望提升 SQL 技能,建议尝试 DataCamp 的 Associate Data Analyst in SQL 职业路径,成为一名熟练的数据分析师。Reporting in SQL 课程也将帮助您熟练构建复杂报表与仪表板,以高效呈现数据。最后,获取 SQL Associate Certification 认证,展示您运用 SQL 解决业务问题的能力,从而在众多专业人士中脱颖而出。


Allan Ouko's photo
Author
Allan Ouko
LinkedIn

数据科学技术写作者,具备数据分析、商业智能和数据科学的一线实践经验。我撰写以行业为导向的实用内容,涵盖 SQL、Python、Power BI、Databricks 和数据工程,并以真实的分析工作为基础。我的写作兼顾技术深度与业务影响,帮助专业人士将数据转化为自信的决策。

常见问答

SQL 中什么是物化视图?

物化视图是一种数据库对象,会将查询结果以物理形式存储,从而通过避免重复计算来优化性能。

物化视图与常规视图有何不同?

与每次访问都会动态检索数据的常规视图不同,物化视图将数据存储为物理表,从而实现更快的查询执行。

完全刷新与增量刷新有何区别?

完全刷新会重新计算整个视图;增量刷新仅更新发生变化的数据,从而提升效率。

哪些数据库支持物化视图?

PostgreSQL、SQL Server(索引视图)、Oracle、Amazon Redshift 和 Azure Synapse Analytics 支持物化视图,且各自具有不同特性与限制;MySQL 缺乏原生支持。

物化视图是否会占用额外存储?

是的,由于以物理形式存储数据,物化视图会增加存储需求。

主题
SQL
数据工程

与 DataCamp 一起学习 SQL

课程

SQL 中级

4 小时
529.3K
在每一步都有实践查询陪伴,这门课程教你立即用自己的 SQL 代码分析数据所需的一切!
查看详情开始课程

创建您的免费账户

实践并学习路径你的进步。

使用 Google 继续
继续操作即表示您接受我们的《使用条款》和《隐私政策》,并同意您的数据存储在美国。
查看更多