数据连接与集成优化管道Dataset projections概述

注意:以下翻译的准确性尚未经过验证。这是使用 AIP ↗ 从原始英文文本进行的机器翻译。

概述

数据集投影可以提高大量查询的性能。如果您有一个数据集,想要针对多种查询模式进行优化(例如,在两个独立的列上进行筛选),您应该考虑为数据集添加投影。投影的具体应用案例列在下面。

每个投影通常支持单一的查询模式,专注于改善一组列的筛选或一组列的合并。可以为一个数据集添加多个投影,并且投影支持所有列类型。此外,投影可以添加到快照或增量构建的数据集中。Noho服务用于管理投影,并在设置投影时在数据集模式中引用。

投影有一些限制:

  • 投影只能添加到仅追加的数据集中。也就是说,只能向数据集中添加行,不能手动从数据集中删除文件或事务。投影系统会自动识别违反此要求的数据集并在其上禁用投影,但作为用户,您仍应避免这种情况。
  • 投影不支持模式演化,即使是增量一致性操作如添加列。

查看下面的示例应用案例,了解投影是否适合您的应用案例。开始学习如何设置投影

应用案例

许多类型的查询将从投影中受益。下面的示例将展示以下内容:

在一列列表上进行筛选

给定一个有序的列列表,优化该列表前缀上的筛选。投影仅会加速将列与常量值进行比较的筛选。而对字符串列的任何筛选必须是区分大小写的。

例如,假设有一个投影专为对列列表["x", "y", "z"]进行筛选而优化。 它将加速以下类型的查询:

  • SELECT * FROM dataset WHERE x = 5 AND y = 10 AND z = '15'
  • SELECT * FROM dataset WHERE x = 5 AND y = 10
  • SELECT * FROM dataset WHERE x = 5 AND q = 3
    • 如果在配置列表以外的其他列上有额外的筛选条件,如本例中的q = 3,Spark会自动尝试解包它可以“推入”数据源的筛选条件(在本例中为x = 5),并在之后应用其他条件。

但以下类型的查询将不会被优化:

  • SELECT * FROM dataset WHERE abs(x) == 10
    • abs(x) == 10不将列与常量值进行比较。
  • SELECT * FROM dataset WHERE x % 100 == 10
    • x % 100 == 10不将列与常量值进行比较。
  • SELECT * FROM dataset WHERE y = 10
    • ["y"]不是["x", "y", "z"]的前缀。
  • SELECT * FROM dataset WHERE z = '15'
    • ["z"]不是["x", "y", "z"]的前缀。
  • SELECT * FROM dataset WHERE x = 5 OR q = 3
    • Spark无法将x = 5的筛选条件“推入”数据源,因为这会错过x = 5为false但q = 3为true的行。

范围查询

投影可以选择性地加速筛选列上的范围查询,例如:

  • SELECT * FROM dataset WHERE x > 5 AND x < 10
  • SELECT * FROM dataset WHERE s LIKE 'SOME_PREFIX%'

限制

  • 无法创建包含非原始类型(例如数组)列并同时支持筛选列上范围查询的投影。

在一组列上合并

给定一组无序的列和一个桶数,仅对该确切的集合和桶数优化合并。

例如,为{"x", "y"}上的合并优化的投影将优化以下类型的查询:

  • SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x AND dataset1.y = dataset2.y

但以下查询将不会被优化:

  • SELECT * FROM dataset1 INNER JOIN dataset2 ON dataset1.x = dataset2.x

合并投影和非投影数据集

在Foundry中,合并大型数据集通常执行排序合并。 这涉及根据合并键对每个数据集进行分区,在该键上对每个分区进行排序,然后合并具有相同键的(排序的)分区。

  • 在一般情况下,这涉及对两个数据集进行洗牌和排序。
  • 如果其中一个数据集的投影已经针对合并列进行了优化,则该数据集将不会被洗牌或排序,但另一个数据集将会被。
  • 如果两个数据集的投影都针对合并列进行了优化,且使用相同数量的桶,则两个数据集都不会被洗牌或排序。这可以显著提高性能。 同样地,将具有合并优化投影的数据集与显式分桶数据集(无投影)进行合并时也适用,但桶数和合并列必须完全匹配。

Foundry中的大多数投影消费者在执行排序合并时不会默认利用投影已经排序的事实,因此您可能仍会在Spark查询计划中看到排序。在变换中,您可以使用 Spark 配置文件 BUCKET_SORTED_SCAN_ENABLED 来根据投影已排序的事实修改Spark的行为,但这并不总是能提高性能,反而可能会使性能下降。

在预先指定的一组列上汇总

在Foundry中,聚合通常涉及对数据集执行洗牌交换(即,根据聚合键对数据集进行分区)。当从哈希分桶的投影(对于所有合并优化的投影都是如此,但对于筛选优化的投影可能不是)读取时,消费者可以避免此洗牌,这可以在聚合过程中显著提高性能。 对于以仅追加方式增量更新的数据集上的主键期望检查 ,投影(在主键列上)尤其有利,既因为投影执行的压缩,又因为可以在用于计算期望的聚合中利用投影的哈希分桶。

从增量管道读取

增量管道可能导致非常高的文件数量,从而导致读取性能下降。例如,每五分钟写入十个分区的管道每年将写入超过一百万个文件。由于诸如简单地产生输入分区列表等原因,这些文件难以读取。

投影提供了一种透明地压缩此类增量管道的方法。只需设置一个优化筛选或合并的投影,读取操作将使用该投影。了解更多关于为增量管道使用投影的信息。

注意,即使投影没有与规范数据集完全同步,只要在投影上次构建时的最新事务和规范数据集上的当前最新事务之间没有SNAPSHOT或DELETE事务(或修改现有文件的UPDATE事务),消费者仍然可以利用投影的筛选或合并优化。

查询上传的数据

CSV是一种查询数据效率低下的文件格式,但通过文件系统源、手动上传等方式上传到Foundry的数据通常最初是CSV格式的。创建一个变换任务是将这些CSV转换为更高效格式(如Parquet)的一种方法。或者,您可以添加一个投影;读取操作将使用优化的投影以获得更好的性能,同时数据集仍包含原始的CSV文件。