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 的 unique_id = 'ID123456' 对所有分区都是通用的,那么现在这并不总是有效,但是如果所有行上都有其他列,它是顺序的或与数据的排序对齐(是您如何摄取数据,因此写入顺序,或者如果您将数据聚集在一起,您如何订购数据)。然后选择过滤列和排序列然后选择完全匹配排序列的聚焦效果。
我们有使用上述模式的非常相似的审计数据,以及我们存储在多个表中的其他数据,其中一些表是超级蒙皮和有序的(通过集群键),然后我们有一个键是 insert_time那个快速表和一个带有所有“额外”的宽/胖 json 表,这些表通常不使用,但以 _insert_time 顺序写入,因此在快速表中找到所需的数据允许读取具有减少分区的宽表。