关于数据库:物化视图如何快速完成数据聚合操作

43次阅读

共计 4042 个字符,预计需要花费 11 分钟才能阅读完成。

SQL 在过来十年逐步走向败落,现在春风吹又生,SQL 正在复苏。随着应用程序变得越来越简单,数据驱动的利用场景越来越多,人们缓缓意识到须要一种数据处理语言。而 SQL 作为一种用于解决结构化数据的机制,它的有效性大家引人注目。

在此篇文章中,咱们将探讨 VoltDB 如何实现物化视图,以及为什么 VoltDB 的物化视图十分迅速。

01 物化视图和一般视图有什么区别?

一般而言,这里会有两种视图:一般视图和物化视图。VoltDB 只应用物化视图,因而咱们偏向于将它们简称为“视图”。
“一般”视图是伪装是数据表的 SELECT 查问语句。在大多数状况下,视图是只读的,这点很重要,因为波及多个表的 SELECT 查问语句可能会非常复杂,而物化视图意味着该简单逻辑只须要执行一次,而后就能够在应用程序中屡次重复应用。
物化视图就像“一般”视图,不过它缓存了后果。

02 为什么晚期的“一般”视图存在各种问题?

起初一般视图很风行,但随着工夫的流逝逐步走下神坛。大多数人想要的视图蕴含诸如 GROUP BY 和 SUM()之类的性能,这意味着该视图每次拜访时都必须遍历大量数据。
因而,如果我有一个视图计算了“每个客户的销售额”,并且想晓得客户“x”的销售额,那么当拜访该视图时,须要计算所有客户的销售额,而后过滤出客户为”x”的那一行。
这显然会很慢,因而一些数据库开发商试图通过应用奇妙的查问优化器来解决此问题,这些优化器须要将视图的 SQL 与要运行的查问合并,人们开始狐疑视图的麻烦超过了它们带来的价值。

03 为什么物化视图做起来不容易?

因为用户心愿应用 GROUP BY 和 SUM()做为视图,然而“一般”视图很慢,因而显著的解决办法是缓存视图的 SELECT 语句的后果,这就是实例化视图的起源。
然而,在老的 RDBMS 中,一般视图到物化视图,带来了问题是根底表上的 UPDATE 和 INSERT 性能却很差。
为什么?咱们设想一下,有一个 3 亿行的表,该表跟踪某人驾驶的汽车的色彩。在该表中插入一行绝对容易,因为咱们每个人只有一行,因而不太可能发生冲突。然而,如果咱们向 GROUP BY ‘car_color’ 添加物化视图,咱们忽然发现咱们的插入内容无奈实现,直到它们排队将物化视图中的行更新为 ’ 红色 ’,’ 蓝色 ’ 或任何其余的什么色彩,之后才能够实现数据的插入。
这种开销在单节点零碎中是不好的,而在集群环境中则更是灾难性的,因为“蓝色”的行可能在不同的服务器上,让问题从单行插入变成了分布式环境下的简单的两阶段提交事务。

04 为什么 VoltDB 的物化视图的性能体现很好?

VoltDB 是一个真正疾速的 OLTP 零碎,咱们心愿它同时能够实现物化视图中的聚合计算。想要了解这一点,须要您更深刻地理解 VoltDB 的体系结构,然而对于本篇文章而言,您须要理解的是:
VoltDB 按 CPU 内核程度划分数据,并为每个 CPU 内核有一个专用线程,该线程按程序解决所有申请。当咱们尝试更新实例化视图总计时,这防止了分布式的竞争操作。

VoltDB 中的物化视图是随着事务产生而自动更新的表。

在解决每个申请时,VoltDB 辨认对其物化视图的本地节点局部做出必要更改。如果该视图称为 SALES_BY_CUSTOMER,则每个分区将具备其本人的子集,并且当“SALES”表产生更新时,数据行插入 SALES 表的同时也会更新物化视图。

更新每个事务的物化视图听起来应该很慢,但实际上每个视图将每个事务的 SQL 速度升高仅仅在 1 -5%。

如果更新表“X”且其视图为“Y”,则对“X”和“Y”的更改是属于同一个事务。VoltDB 中的物化视图无需从新计算,并始终反映以后最新的数据状态。

因而,在 VoltDB 中读取实例化视图的老本简直与读取表的老本雷同:<1 毫秒。

如你所见,物化视图的实现并不是一件容易的事,然而如果能做好,它们能够提供对聚合数据的真正即时可视性,下层利用开发工作将变得轻松很多。
当初让咱们进入 VoltDB 的物化视图利用场景。

4.1 物化视图:在实时数据流中的聚合场景

一种常见的模式是应用实例化视图按秒聚合高速事件流,而后应用 SQL 查问按分钟,小时或其余单位进一步聚合。这样能够疾速聚合不同粒度级别的工夫序列数据。
这是从 VoltDB 下载工具包中蕴含的工夫 window 应用程序中的示例,该应用程序依据用户指定的工夫范畴计算平均值:

CREATE TABLE timedata
(uuid VARCHAR(36) NOT NULL,  val BIGINT NOT NULL, 
 update_ts TIMESTAMP NOT NULL 
); 
CREATE VIEW agg_by_second 
( 
 second_ts, 
 count_values, 
 sum_values 
) 
AS SELECT TRUNCATE(SECOND, update_ts), COUNT(*), SUM(val) 
 FROM timedata 
 GROUP BY TRUNCATE(SECOND, update_ts); 
— Find the average value over all tuples across all partitions for the last 
— N seconds, where N is a parameter the user supplies. 
CREATE PROCEDURE Average AS 
 SELECT SUM(sum_values) / SUM(count_values) 
 FROM agg_by_second 
 WHERE second_ts >= TO_TIMESTAMP(SECOND, SINCE_EPOCH(SECOND, NOW) – ?);

VoltDB SQL 反对将工夫戳转换为 SECOND,MINUTE,HOUR,DAY,DAYOFMONTH,DAYOFYEAR,MONTH,WEEK,WEEKOFYEAR,WEEKDAY 和 YEAR 的性能,所有这些都能够与视图定义和查问混合并匹配。

4.2 物化视图:横向扩展性场景

因为物化视图的大小与 VoltDB 的其余部分一样,因而能够在疾速传入的写入 / 更新工作负载中调配汇总计算的老本,并使疾速读取状态汇总的老本十分低廉。
在下面的示例中,如果以 15k / sec 的速率插入元组并且有四个分区,那么要计算最初十秒的平均值,VoltDB 将须要扫描 15 万行。应用实例化视图时,它须要每秒扫描 1 行乘以分区数,即 40 行。以秒为单位事后汇总表的总和和计数具备微小的劣势。

05 如何联合流式数据分析与单个事件决策?

因为物化视图始终是最新的,在事务上是统一的并且能够通过规范 SQL 拜访,因而在运行事务时,能够轻松应用视图中保护的聚合。
咱们的选民示例是这样做:该示例保护一个物化视图,视图是按电话号码对传入记录进行分组,强制每个电话号码投票限度的事务应用该视图查找传入电话号码注册的先前呼叫。一个更简单的示例能够应用下面探讨的工夫序列函数来强制执行每分钟最大访问量,以实现高速配额执行。
当初,让咱们应用表决器示例来展现在可伸缩摄取工作负载中摊派聚合老本的运行时劣势。该示例包含一个热图,该热图绘制了在每个州中哪个参赛者领导投票的图表。当然,查问该热图的数据须要按州计数选票。
应用实例化视图,这能够在亚毫秒级的工夫内实现(它须要为六个参赛者的每个分区读取 50 行)。反之,如果没有实体化视图,则必须扫描所有投票,并且须要破费大量执行工夫(并且须要读取数百万行)。
以下是一些具体数字,它示意显示在最新的 Intel Core i7 CPU 上每个分区大概 10GB 数据(约 1.3 亿行)的执行工夫(没有物化视图,将扫描所有 1.3 亿行,执行工夫约为 8 秒):

26> select state, count(*) from votes where state=’MA’group by state; 
STATE C2 
—— ——– 
MA 3,839,860 
(Returned 1 rows in 8.13s) 
With the view execution time is sub-millisecond: 
31> select state, sum(num_votes) from v_votes_by_contestant_number_state where state 
=‘MA’group by state; 
STATE C2 
—— ——– 
MA 3,839,860 
(Returned 1 rows in 0.00s)

视图的实现对数据摄取的工作量有肯定的影响,然而即便应用物化视图,数据库每个内核每秒也能够解决超过 4 万个申请。视图开销能够通过程度可伸缩性来弥补—所需的工作能够跨内核和集群中的服务器扩大。这种衡量使得能够在高吞吐量的每个事件事务中应用实时聚合。
v_votes_by_contestant_number_state 视图显示 1 个分区吞吐量:

Throughput 42252/s, Aborts/Failures 0/0 
Throughput 45407/s, Aborts/Failures 0/0 
Throughput 46352/s, Aborts/Failures 0/0 
Throughput 44341/s, Aborts/Failures 0/0

1 个没有 v_votes_by_contestant_number_state_view 的分区吞吐量:

Throughput 50525/s, Aborts/Failures 0/0
Throughput 52503/s, Aborts/Failures 0/0
Throughput 50961/s, Aborts/Failures 0/0
Throughput 51190/s, Aborts/Failures 0/0

06 总结

VoltDB 是一个内存 ACID 向外扩大 SQL 数据库。它每秒能够解决数万至数百万个事务,还可能针对高速数据流进行实时 SQL 剖析。
VoltDB 实时剖析性能的重要局部围绕其物化视图实现而构建。VoltDB 的物化视图反对实时汇总和摘要,并反对将实时剖析与按事件决策联合在一起。

如果您对 VoltDB 的工业物联网大数据低提早计划、全生命周期的实时数据平台治理等感兴趣,欢送私信,进入到咱们的官网交换群。

正文完
 0