乐趣区

关于存储:实时数仓入门训练营Hologres性能调优实践

简介:《实时数仓入门训练营》由阿里云研究员王峰、阿里云资深技术专家金晓军、阿里云高级产品专家刘一鸣等实时计算 Flink 版和 Hologres 的多名技术 / 产品一线专家齐上阵,合力搭建此次训练营的课程体系,精心打磨课程内容,直击当下同学们所遇到的痛点问题。由浅入深全方位解析实时数仓的架构、场景、以及实操利用,7 门精品课程帮忙你 5 天工夫从小白成长为大牛!

本文整顿自直播《Hologres 性能调优实际 - 清芬》
视频链接:https://developer.aliyun.com/…

内容简要:

一、Hologres 建表最佳实际

二、Hologres 性能问题剖析与优化

一、Hologres 建表最佳实际

(一)建表优化的必要性

为什么 Hologres 建表优化十分重要?

首先,对于整个的查问性能以及写入性能来讲,一个好的建表跟一个比拟差的建表,性能下面有十分大的区别。

其次,建表优化须要尽早做,是因为 Hologres 在改 DDL 的同时,有可能须要用户反复进行一些数据导入,这种反复的工作使得咱们心愿尽早实现建表优化。

最初,一个好的建表对于用户的数据存储老本也有肯定的帮忙。如果建表做得不失当,可能导致建一些不必要的 Index,而后导致数据多了一些冗余的存储,从而晋升了老本。
因而,建表优化是十分重要的,这也是把它作为本文第一局部的起因。

(二)业务建模是性能优化的前提


说完建表的重要性之后,咱们再看建表优化之前要去做整个业务建模的优化。在思考应用 Hologres 的同时,咱们要晓得通过 Hologres 可能解决什么样的业务问题,以及通过什么样的形式解决。

Hologres 自身是一个 HASP 产品,在应用 Hologres 的同时就须要跟业务场景联合,咱们要晓得这个场景到底是剖析场景还是在线服务场景。如果是一个剖析型,就用 Hologres 的列存比拟敌对,如果是一个在线服务型场景,就用行存比拟敌对,这些是跟业务场景相干的。

第二个是要可能联合 Hologres 自身的产品劣势。Hologres 是一个在线服务以及交互式剖析的产品,它并不适宜 ETL 以及海量数据拖取的场景。因而,在把业务往 Hologres 下面搬的时候,不能搬所有的场景,否则可能导致 Hologres 做一些不太适宜自身的事件,信赖就会不太好。

第三个是须要做一些取舍。为了达到预期的性能,可能须要做一些相似预计算或者数据加工的提前操作,缩小后续计算复杂度,放慢计算速度。

以上这些都跟事后数据建模以及整个业务冀望非亲非故。

(三)存储形式的抉择

做完以上筹备工作之后,咱们须要进行 Hologres 治理存储形式的抉择。

Hologres 自身反对两种存储形式,别离是行存和列存。

行存次要的利用场景是对主键进行高 QPS 查问,并且当咱们表比拟宽的时候,一次查问会读取大量列,这种场景实用 Hologres 是非常适合的。

除此之外,Blink 的维表查问必须是用行存,因为个别状况下 Blink 的维表是高 QPS、基于 Key 的查问,列存没有方法扛住这么高的压力。

列存实用于简单的交互式剖析查问,比方一个查问外面,它有关联、聚合等等各种各样的简单计算。同时它笼罩的场景十分多,包含过滤、聚合等,列存是比拟通用的存储形式。
行存次要实用于在线服务类的场景,列存次要实用于剖析型的场景,这是两个存储形式的抉择区别。

(四)优化 Shard 数

Shard_count: Shard 实现了物理分表的成果,多个 Shard 并行服务查问。
减少 Shard 能够减少查问的分布式并行度,更多 Shard 不肯定查问更快,也会带来并发查问的调度开销。

说完存储形式,接下来咱们看 Shard 数。

Hologres 在存储的时候,是把物理表分成一个个 Shard 存储,每个表会依照肯定的散布形式散布到所有的物理节点下面,而后每个 Shard 能够去并发进行查问,Shard 数越多,相当于整个查问的并发度越高。然而 Shard 数也不是越多越好,因为它自身有一些额定的开销,所以咱们须要依据整个查表的数据量以及查问复杂度来设计每个表的 Shard 数。

在集群扩容的时候,比方咱们本来是 128 Core 的实例,扩容到 256 Core 之后,咱们须要对整个 Shard 数进行肯定的调整,这样能力享受扩容带来的性能晋升。

因为咱们整个并发度是在 Shard 数下面,如果实例扩容了,然而 Shard 数没变,那么相当于整个计算的并发度没变,这种状况会导致尽管扩容了,然而查问性能没有晋升。

个别状况下,咱们会倡议用户将 Shard 数设置成跟实例规格差不多的数量,比方一个 64 Core 的,Shard 数设成 40 或 64 这种比拟贴近于实例规格的数量。当规格往上涨之后,咱们心愿 Shard 数也能往上涨,从而进步整个查问的并发度。

(五)优化 Distribution Key

而后说完 Shard 数之后,咱们再看一下 Hologres 外面十分重要的 Distribution Key,它次要是用来决定数据如何分到每个 Shard 下面。

Distribution_key: 平衡地散发数据到多个 Shard 中,令查问负载更平衡,查问时间接定位到对应 Shard。

如果创立了 Primary Key 索引(用于数据更新),默认为 distribution_key,Distribution_key 如果为空,默认是 Random,Distribution_key 需是 Primary Key 的子集。

一个好的 Distribution Key 设计,首先要求用户的数据在 Distribution Key 上划分比拟平均。

比方用户 ID 或者是商品宝贝 ID,个别状况下 Key 只有一个,所以它是十分平均的,是用来作为 Distribution Key 十分好的例子。然而像年龄或者性别这种就不太适宜作为 Distribution Key,因为它可能会使大量的数据 Shuffle 到一个节点上,导致整个数据的散布不是很平均。

Distribution Key 次要的作用是缩小关联查问、聚合运算里数据的 Shuffle。

如果用户没有设置 Distribution Key,那么咱们默认是 Random,因为咱们会保障用户的数据可能尽可能平均地散布到所有 Shard 下面。

接下来咱们看一下 Distribution Key 次要的作用。

在 Hologres 外面咱们会有不同的表,放到不同的 TableGroup 外面,对于 Shard 数雷同的表,都会放到一个 TG 上面。

假如两个表做关联,如果都依照关联的 Key 去设计 Distribution Key,那么这两个表的关联就能够做一个 Local Join,如上图右边所示。所有的数据不须要做额定的 Shuffle,每个表在每个 Shard 下面,做完关联之后间接产生后果。

如果数据量增大,之后可能须要扩容,咱们心愿在这个 TG 上面所有表都会进行扩容,这样能保障数据分布的一致性,维持住整个 Local Join,而不会因为扩容导致做不了 Local Join。

Local Join 相比于非 Local Join,性能差异十分大,通常会有一个数量级左右的差别。
跟 Local Join 最相干的就是 Distribution Key 的设计,如果 Distribution key 设计不合理时,在 Join 时,可能引起大量的 Data Shuffle,影响效率。

如上图所示,假如表 A 跟表 B 要做一个关联,如果不是 Distribution Key 的场景,那么咱们就须要把表 A 的数据跟 B 的数据都依照它的 Join Key 做 Shuffle,Shuffle 会带来十分昂扬的老本,同时影响整个查问的效率。

所以通常状况下,对于须要连贯的表,能够把 Join 关系设为 distribution key,实现 Table 在同一个 Shard 内 Local Join。

(六)优化分区表

分区表: 也是物理表,具备一样的 Shard 能力,但多了一个依据分区键进行 Table Pruning 的能力。

如上图所示,假如查问的过滤条件只命中了局部的分区,那么剩下的分区表就不须要进行扫描,这可能大大节约整个查问的 IO,放慢查问速度。

通常状况下,分区的 Key 是动态的,并且数量不会太多,最适宜做分区 Key 的是日期。例如有的业务方是一天一个分区,或者按小时分区,那么查问的时候也会依照某一段时间来过滤数据。

通过分区表,当用户的查问条件蕴含工夫过滤时,就能够把不必要的分区过滤掉,对查问性能有很大的的晋升。

通常将日期列等基数低(小于一万)的字段用于做分区字段,如果分区表过多,而查问时不带有分区过滤条件,性能会降落。

(七)优化 Segment Key

Shard 是一个逻辑数据单位,物理上是一组文件(散发到同一个 Shard 的多个表,以及对应的索引)。

Segment Key 次要是作用于列存。

在列存下面,文件是存成一个个 Segment,当查问到了某一个 Shard 上,因为 Shard 外部有一堆的文件,咱们要去找哪些文件会命中这个查问,须要进行扫描,Segment Key 是用来跳过不须要查找的文件。

假如 Segment 设成了一个工夫,数据依照工夫写入,比方 10 点到 11 点是一个文件,11 点到 12 点是一个文件,12 点到 13 点是一个文件。当咱们要查问 12:15~12:35 区间范畴的数据,对于这种状况,通过 Segment Key 就能疾速找到 12 点到 13 点这个文件命中查问,所以只有关上这一个文件就能够了。通过这种形式就能够疾速跳过不必要的文件扫描,缩小 IO,让整个查问更快。

上图次要是介绍了整个数据的写入流程,帮忙大家了解 Segment Key 到底是什么样的。

方才提到当数据写入 Hologres,会写到内存表外面,内存写满了,异步 Flush 到文件,Append Only 写入,写入效率最高。因为写入时为了性能,没有全局排序和单文件更新,文件之间存在 Overlap。

这是什么意思?

Segment_key 用于文件块的边界划分,查问时基于 Segment_key 能够疾速定位数据所在文件块,Segment_key 多列时,依照左对齐。

如上文提到的例子,11 点到 12 点在一个文件是比拟现实的状况,理论状况可能是 11 点到 12 点在一个文件,11:30~12:30 是在第二个文件外面,12:30 ~13:00 又是一个文件,文件之间可能存在重叠。查问可能会命中多个文件,这种场景可能就会导致须要关上多个文件。

所以在设计 Segment Key 的时候,尽可能不要有 Overlap,尽可能程序地递增。如果数据写入十分无序,比方写进来的数据,先是 123,而后 678,而后 456,这种乱序的写入就会导致 Segment Key 可能在不同的文件外部有反复的数据,使得 Segment Key 齐全没有起到查问过滤的作用。

因而,设计 Segment Key 最要害的一点就是尽可能枯燥,并且没有 Overlap,这样才能够让咱们可能尽可能跳过这种不必要的数据扫描。

Segment Key 的设计次要是用在 Blink 的实时写入场景,并且把 Key 设成工夫字段,因为它数据实时写入的工夫是递增的,并且每个值不会有很大的 Overlap,比拟适宜用 Segment Key。

除此之外,其余的场景不太倡议用户本人设 Segment Key。

(八)优化 ClusteringKey

Clustering_key,文件内聚簇布局,示意排序信息,和 MySQL 的聚簇索引不同,Hologres 用来布局数据,不是布局索引,因而批改 Clustering 须要从新数据导入,且只有一个 Clustering_key,排序操作在内存中实现生成 SST。

上图为一个例子,上图的右边是一个齐全无序的状况,如果依照 Date 作为 ClusteringKey,那么会变成右上角的图。依照 Date 做完排序之后,当进行 Date 查问,比方 Date 大于 1 /1,小于 1 / 3 的数据,能够疾速查到对应的时间段。

假如没有做这个 Index,咱们就须要把所有数据都扫一遍,这就是通过 ClusteringKey 减速查问的原理。

假如依照 Class 做排序,如果将 Class 和 Date 作为 ClusteringKey,那么会先依照 Class 做排序,而后再依照 Date 排序,如上图右下方所示。对于这种场景,ClusteringKey 的设计是依照最左匹配的准则,就是当遇到用户的查问条件,也依照最左匹配的准则来匹配。

例如,查问的 Key 是 Class,那么可能命中 ClusteringKey,如果查问条件是 Class 跟 Date,也可能命中 ClusteringKey,但如果查问条件只有 Date,则无奈命中 ClusteringKey。遵循的最左匹配相当于,从左往右的条件中,无论用户的查问条件有几个,最右边的条件必须匹配上才能够。

ClusteringKey 次要的作用是可能减速查问的过滤,Range 查问的过滤以及点查的过滤。ClusteringKey 的毛病是每个表最多只能有一个 ClusteringKey,只能有一种排序形式。

(九)优化字典编码

字典编码对于字符串类型能够无效压缩,特地是基数小的列。编码值能够放慢比拟操作,对于 Group By,Filter 有益处,Holo 在 0.9 之后主动设置。

上图为字典编码的一个例子。

如上图右边所示,有 Card No 和男女性别 Gender。因为男女性别只有两个值,所以非常适合于用字典编码,如果把性别编码成 0 跟 1,就变成了图两头的形式。

当进行数据查问的时候,须要对过滤条件的编码,比方想查所有男性的 Card No,过滤条件就变成了 Gender 0,通过这种形式进行数字查问。

然而字典编码有一个毛病,就是对于基数列比拟大的场景,它的开销十分高。

因为咱们对数据先进行编码,编码的过程中,如果数据一共是 100 万行,其中有 99 万行不一样的值,这会导致咱们有 99 万个 Encoded 值,这种状况会造成整个编码跟查问的耗损十分高,这种状况就不太适宜做字典编码。

在 Hologres0.9 之后,咱们反对主动设置字典编码,用户无需本人去配置字典编码。

(十)优化位图索引

位图索引,对于等值过滤场景有显著的优化成果,多个等值过滤条件,通过向量比拟计算。

位图索引相当于把每列的数据通过位图来标识它是否存在。

如上图所示,咱们将右边表中学生的性别、班级进行位图编码,就失去了左边的图,通过这些位图信息咱们能够进行疾速过滤。

例如,咱们要查所有男性学生,能够通过“1 0”进行过滤,失去右图中 PK 值为 1、2、5、6 这四行合乎查问条件的数据。假如要过滤出三班的同学,那么咱们再构建一个位图“0 0 1”,再跟班级的数据做一个过滤,就能失去 PK 值为 2 和 6 的信息。

能够看到,位图索引次要的利用场景是在点查,比方查问条件是男性并且年龄等于 32 岁,这种场景也是非常适合用位图进行查问减速。

同样的,位图索引也有个问题,就是基数过多的列,在位图索引编码时,会造成稠密数组(列很多,值很少),对查问性能改善影响小。

(十一)物理拓扑

上文论述了几个索引以及整个存储形式,上面看一下如何区别它们,以及整个用户视角看起来它大略是什么样的形象。

如上所示,用户写了一个 SQL 之后,首先会依照用户分区键路由到对应要找的表下面,找对逻辑对象 Table。

第二步通过 Distribution Key 找到对应 Shard。

第三步是 Segment Key,找到 Shard 之后要找对应 Shard 下面的文件,因为理论数据是存储成一个个文件,咱们通过 Segment Key 找到想要关上的文件。

第四步是在文件外部,数据是否有序,这是通过 Clustering Key 来查找的,Clustering Key 帮忙咱们找对理论文件区间。

第五步是 Bitmap。因为 Hologres 把数据依照一个个 Batch 存储,在一个 Batch 外面,咱们须要通过 Bitmap 疾速定位到某一行,否则须要把某一个区间范畴内所有的数据扫一遍。
图中从上往下不同的过程,越来越到文件外部,越往上是越大的范畴。

二、Hologres 性能问题剖析与优化

(一)性能白皮书

用户问得最多的问题是 Hologres 的性能如何,咱们有一个大略的性能估计。

应用 Hologres 时,实时写入单 Core 的 QPS 是 5000,对于离线写入的场景,比方 Max Computer 写入到 Hologres,通常状况下单 Core 的 QPS 能到 5W。对于 OLAP 查问,单 Core 解决 200 万数据量。对于点查场景,单 Core QPS 在 1W 左右。

用户能够依据以上信息来评估本人的查问以及业务场景须要用多少资源。

(二)实时写入与点查

对于不同的利用场景,咱们优化伎俩是不太一样。

对于实时写入与点查的场景,首先要查看建表是否适合。对于高 QPS 写入以及点查来说,咱们心愿 Distribution Key 和查问条件统一。因为 Distribution Key 用来找到对应的 Shard,在写入的 QPS 很高的状况下,如果过滤条件与散布 Key 统一,咱们就能够疾速路由到某一个 Shard 下面,这个查问就不须要发到所有 Shard 上,对这种场景有很大的性能晋升,所以要求 Distribution Key 和查问条件统一。

第二个是咱们的表最好是行存表,因为行存表对实时写入以及点查在性能上十分敌对。

第三个场景是假如不是行存表而是列存表,咱们心愿 Pk、Clustering Key 和查问条件统一,这样能力用上 Clustering Index 的能力。

除了建表优化以外,还须要优化查问写入代码。因为如果写 Hologres 的代码设计得不合理,会带来十分昂扬的额定老本。可能用户会发现 QPS 如同曾经上不去了,但其实 Hologres 外部 CPU 使用率非常低,这是因为用户本人的写入代码不是特地高效。

对于这样的问题,首先咱们心愿用户尽可能通过 Preparestmt 的形式,它次要的益处是可能节约整个执行打算的开销。提交一个 SQL 之后,个别会把 SQL 进行编译解析,而后生成一个执行打算,最初提交到执行引擎来执行这样的一个过程。当数据反复执行 SQL 的时候,应用 Preparestmt 就能够不必再去做生成、执行打算、解析的过程,老本大大减少,查问和写入的 QPS 会更高。

第二点是咱们心愿用户写入的数据尽可能凑批。比如说咱们常常会碰到一些用户,他会先写 insert into values1 和 insert into values2,再写 insert into values2 和 insert into values3,而后不停地发这种小的 SQL 进行数据插入,这会带来十分昂扬的数据 RPC 老本,同时整个 QPS 也上不去。

咱们通过凑批能够让写入性能会高很多,比方通过 insert into values 的形式,一个 values 外面就蕴含了 1000 个值或者 1 万个值,这 1 万个值的写入只有一次数据传输就能够了。相比于之前的形式,性能上可能存在 1 万倍的差别。

第三块是整个 Holo Client 的应用,有的用户可能不太分明如何优化代码,或者不能凑好批,Holo Client 能够帮忙用户解决这些问题。

相比于传统的 JDBC Client,Holo Client 帮用户做了各种各样异步化的封装以及凑批的逻辑,并且它没有 SQL 引擎的额定开销,不须要进行一些 SQL 解析的操作,所以它的写入跟查问性能相比于应用 JDBC 的形式会好十分多。

Holo Client 也是 Blink Client 写入的内置插件,所以它相比用户本人的工具,写入性能会更好。

还有一点是咱们连贯的时候尽可能应用 VPC 域名进行数据的写入跟查问。

因为间接用公网的话,网络之间的 RT 比拟高。如果用 VPC 网络,因为是在同一个网站内,机器之间的 RT 比拟低,可能缩小整个网络下面的开销,在很多利用场景下,它的影响十分大,也十分重要。

(二)离线写入与查问常见问题

接下来咱们看一下离线写入与查问常见的问题。

为什么把离线写入跟查问放在一起?这是因为离线写入跟查问是一样的原理,离线写入也是通过跑一个 Query,跑 Query 形式的问题都是差不多的。

首先是统计信息缺失。

Hologres 自身是一个分布式引擎,它要把用户写的 SQL 运行在分布式引擎上,因而须要去优化器生成一个执行打算,优化器须要统计信息来帮忙它生成一个比拟好的执行打算。当遇到用户统计信息缺失,优化器相当于丢失了输出,无奈生成执行打算,这是咱们在线上遇到最大也是最多的一个问题。

第二个很大的问题是建表不优,当遇到建表跟查问不统一的状况,就会导致整个查问的性能十分差。

除此之外,Hologres 是一个自研的引擎,然而为了兼容 Postgres 的开源生态,所以会有一个联邦查问的机制,使得用户能在 Postgres 运行的 Query 也能在 Hologres 运行,然而它会带来一些额定的性能损失。

(三)查看执行打算

执行打算的好坏对于查问性能影响十分大。Hologres 的查问优化器会依据 Cost 抉择执行耗时最低的查问打算来执行用户的查问,不过难免会呈现一些查问打算不优的状况。用户能够通过 Explain 命令来查问执行打算,执行打算中个别蕴含以下算子:

1. 数据扫描算子:Seq Scan、Table Scan 及 Index Scan 等。

次要是用来进行数据拜访,Seq Scan、Table Scan 及 Index Scan 别离对应程序扫描,表扫描以及基于 Index 的扫描。

2. 连贯算子:Hash Join 及 Nested Loop。

Hash Join 的意思是两个表做关联的时候,会先把一个表做成 Hash Table,另外一个表通过 Hash Table 的 Lookup 进行关联查问。

Nested Loop 会把两个表做成两个 For 循环,在表面就是一个表 For 循环遍历所有的数据,另外一个表也是 For 循环,这就是 Hash Join 与 Nested Loop 的区别。

3. 聚合算子:Hash Aggregate 及 Streaming Aggregate。

基于 Hash 查找的 AGG 实现及基于排序的 AGG 实现。

4. 数据挪动算子:Redistribute Motion、Broadcast Motion 及 Gather Motion 等。
Hologres 是一个分布式的引擎,所以难免会碰到数据 Shuffle 的状况。Redistribute Motion 次要是做数据的 Shuffle,Broadcast Motion 是做数据播送,Gather Motion 是把数据拉到一起,这些数据挪动算子次要是用来解决分布式数据的问题。

5. 其余算子:Hash、Sort、Limit 及 Append 等。

(四)统计信息缺失

咱们在看 Query 性能的时候常常会碰到几个问题,其中一个是统计信息缺失,咱们如何晓得统计信息是否缺失?

上方是一个 explain 查问的例子。当 Hologres 没有统计信息,行数的默认值是 1000。这里咱们能够看到,以后 tmp 和 tmp1 两个表的行数都是 1000,表明这两个表目前都拿不到统计信息。

没有统计信息容易呈现的问题:

跑查问 OOM

写入性能差

(五)更新统计信息

那么咱们怎么解决没有统计信息的问题?

通过 Analyze 命令,用户能够更新统计信息。

还是之前的例子,通过 analyze tmp; 和 analyze tmp1,能够看到这两个表就有统计信息了,如上方所示。

从上方能够看到,tmp1 有 1000 万行数据,它 1000 万数据 Join 1000 行数据,此时咱们发现,这个表尽管做了个 Hash Join,但它的 Join 程序是不对的。因为在这之前 tmp 的数据量十分小,而 temp1 数据量十分大,会导致把 tmp1 放到了 Hash Table 这一侧,而后 Hash Table 十分大,导致整个 Join 性能十分差。

通过 Analyze 之后,能够把 Join 的程序调过来,把小的表 tmp 放在被 Hash 这一侧,把大的表 tmp1 放在关联的那一侧,造成一个比拟好的查问打算,查问性能相比之前也有一个比拟大的晋升。

(六)抉择适合的散布列

咱们须要抉择适合的散布列,也就是本文后面提到的做 Local Join 的状况。如果用户不设置散布列,在进行关联查问时,Hologres 须要将 2 个表的数据依据 join key shuffle 到一起,保证数据的正确性。如果 shuffle 的数据量很大,会造成很高的查问提早。

咱们如何判断有没有做 Local Join?

在上方示例中咱们能够看到,通过 explain 查看执行打算,Redistribute Motion 示意 Shuffle 算子,tmp 和 tmp1 两个表在做关联之前都通过 Join 条件作了 Shuffle,这阐明整个关联不是一个 Local Join。

解决办法是把关联 Key 设置成 Distribution Key。

具体做法是从新建表,关联 Key 设成 a 跟 b,此时咱们再去查看执行打算,就没有 Redistribute Motion 了,这个关联就是一个 Local Join。

通过这种形式就能够让整个关联从非 Local Join 变成了 Local Join,性能绝对之前也有一个比拟大的改善。

(七)判断是否用上 Clustering Key

接下来看一下怎么通过执行打算来看咱们之前的那些建表的 Index,判断是否用上 Clustering Key。

如上方所示,如果咱们写了个查问:

explain select * from tmp where a > 1;

假如 a 字段是个 Clustering Key,此时咱们在 explain 查问的执行打算中能够看见有一个 Cluster Filter,示意咱们曾经用上 Clustering Key。

(八)判断是否用上 Bitmap

接下来咱们判断是否用上 Bitmap。

如上图所示,咱们的查问条件是:

explain select * from tmp where c = 1;

这个 c 是 Bitmap Key,在执行打算能够看到有 Bitmap Filter:(c = 1)这样一个过滤条件,此时咱们就晓得用上 Bitmap 了。

(九)判断是否用上 Segment Key

接下来判断是否用上 Segment Key。

如上图所示,咱们的查问条件是:

explain select * from tmp where b > 1;

这个 b 是 Segment Key,咱们在执行打算能够看到有 Segment Filter:(b > 1)这样一个过滤条件,此时咱们就晓得用上 Segment Key 了。

通过以上几个 explain 查问的例子,咱们就能晓得查问是否用上之前建表的 Index,如果没用上,阐明有可能建表不对,或者查问模式并没有很好地适配建表。

(十)联邦查问优化

在 Hologres 外部有两套计算引擎,其中一套是齐全自研的 Holo 计算引擎,它的性能卓越,但也是因为它是齐全自研的,所以相较于开源的 Postgres 计算引擎,它无奈在一开始就反对所有 Postgres 的性能,会有局部 Postgres 性能缺失。

另一套计算引擎是 Postgres,它是齐全开源生态的,性能方面比自研的计算引擎稍差一些,然而它齐全兼容 Postgres 性能。

因而,在 Hologres 外面,一个查问有可能会既用到 Holo 计算引擎,也用到 Postgres 计算引擎。

(十一)优化联邦查问

判断是否应用了联邦查问,咱们能够通过 explain。

Hologres 自研引擎不反对 not in,对于查问:

explain select * from tmp where a not in (select a from tmp1);

如下所示:

从执行打算能够看到有 External SQL(Postgres):这样的一个算子,这就标识了查问引擎跑到了 Postgres 引擎下面去执行。

因为 Holo 计算引擎不反对 not in,所以说这部分的计算是在 Postgres 下面执行的。当看见 External SQL(Postgres):这个算子,用户须要警觉当下用到了 Holo 计算引擎不反对的性能,此时最好通过查问改写,换成 Holo 反对的算子来执行它的 Query,从而晋升查问性能。

对于下面这个例子的场景,咱们能够通过将 not in 改为 not exist:

explain select * from tmp where not exists (select a from tmp1 where a = tmp.a);

当用户这个表肯定是非空,那么能够把 not in 间接改成 not exit,之后再查看执行状况,会发现整个 Query 都是在 Holo 引擎下面,没看到方才的 External SQL(Postgres)算子。

这个查问生成的执行打算相比之前在 Postgres 引擎上执行的打算,查问性能上可能会有数倍的差异。

通过上述所有的例子,咱们就理解了 Hologres 性能调优整个过程,以及其中须要留神的关键点,欢送感兴趣的同学多多关注与应用 Hologres。

原文链接
本文为阿里云原创内容,未经容许不得转载。

退出移动版