变量列中唯一元素的雪花查询性能

时间:2020-05-28 02:21:35

标签: snowflake-cloud-data-platform

我正在查询一个包含大量TB的半结构化json数据的Snowflake视图。当我在感兴趣的变量列中查询记录中不唯一的元素时,结果将在几秒钟内返回:

SELECT json_data:element1 FROM table WHERE json_data:common_category = 'CATEGORY1';

当我在感兴趣的变量列中查询记录中唯一的元素时,运行时会变慢一些我还没有达到的时间:

SELECT json_data:element1 FROM table WHERE json_data:unique_id = 'ID123456';

我相信,将唯一元素展平为Variant列之外的关系形式可以提高性能,但是我不是具有这些权限的DBA。有什么方法可以调整我的查询,以便基于变体列json数据查找单个记录将产生可接受的性能?

1 个答案:

答案 0 :(得分:2)

Snowflake将内部变体(json)数据存储在一个独立的列(如100多个最常见元素的结构)中,其余数据存储在一个剩余的列(如该列)中。这些虚拟列具有最小值/最大值,分布与普通列一样,就像统计数据一样。

notes 1 notes 2

这意味着在数据的主要列上,它们可以修剪大量不需要的分区以进行读取(如果您的数据自然地按有帮助的方式排序)。

这还意味着,如果您使用的是JSON中的几列,则它只会读取这些条带,从而减少IO。

同样,当您像在此处那样选择整个blob时,第二点也不会起作用,因为SELECT的READ和WHERE的READ相同。

因此,对于您的查询,您将看到第一个查询中所有少量的分区。 对于第二个查询,您将看到它计划读取所有分区。

如果您将第一个查询更改为:

SELECT json_data:common_category FROM table WHERE json_data:common_category = 'CATEGORY1';

您将看到读取的分区数与第一个示例相同,但读取的字节数应为分数。

与普通表一样,您应始终命名所有列,并避免使用SELECT * FROM TABLE,因为该计划知道要提取的内容。当您命名所有一阶列和所有变体列时,将看到统计上更快的编译时间。

在使其更快的情况下:

如果您必须具有所有JSON列,然后

SELECT json_data FROM table WHERE json_data:common_category = 'CATEGORY1';

具有可接受的速度然后执行:

SELECT json_data:common_category FROM table WHERE json_data:unique_id = 'ID123456';
SELECT json_data FROM table WHERE json_data:common_category = <answer from prior> and json_data:unique_id = 'ID123456';

这样,第一个查询从所有分区中读取最少的量,第二个查询从必须读取的分区中读取所有量。.

例如,如果common_category的{​​{1}}对于所有分区都是公用的,但是现在这并不总是有效,但是如果所有行上都有其他列,则该列是连续的或与数据(例如,如何摄取数据从而写入顺序,或者如何对数据进行聚类(如果已将其聚类))。然后选择过滤器列和订单列,然后选择具有订单列聚焦效果的完全匹配项。

我们具有使用上述模式的非常相似的审核数据,并且我们存储在多个表中的其他数据,其中一些表是超级外观并经过排序(通过集群键),然后我们的键为insert_time快速表和带有不经常使用的所有“额外”的宽/胖json表,但都以_insert_time顺序写入,因此在快速表中找到所需的数据可以读取分区减少了的宽表。