我在SnowFlake中有一个表。当我执行 SELECT
查询,结果集包含千兆行。我需要一次处理大约10000行。因此,我使用了一个通过偏移的批处理机制(我做了个 SELECT *
与 LIMIT 10000 OFFSET desired_offset
).
我使用SnowFlake的缓存机制来重用计算结果。所以我运行第一个查询(返回gigs的行数)一次,然后用不同值的 offset
.
然而,随着偏移量不断变大,查询执行时间变大。一些初步的基准测试表明,查询执行时间为 正比 的偏移量。因为offset达到了gigs的值,所以每次查询的时间就变成了分钟,随后是小时。这成为一个非常漫长的过程。
我想知道是否有办法可以优化这个过程。请注意,我不允许在结果集之上创建视图,或者将结果集存储为另一张表(即,我只想在db上拥有读权限)。
下面应该提供我正在运行的查询的要点。
第一个查询是获取结果集
SELECT *
FROM my_table
WHERE some_condition;
随后的查询
SELECT *
FROM table(result_scan('query_id_of_first_query'))
LIMIT 10000 OFFSET desired_offset;
下面是执行时间与偏移值的基准测试。
10^5 | 982ms
10^6 | 1.79s
10^7 | 12.59
10^8 | 1m 57s
10^9 | 19m 41s
3*10^9 | 1h 4m 55s
为了补充一些细节
上面的基准测试是针对 小型 仓库。我也试过用 大型 仓库,正如预期的那样,它将运行时间减少到了25%。
但是,我需要更多的 "软件 "方法,而不是 "硬件 "方法:) .
这是一个很好的问题,你能不能扩展一下 "我不允许将结果集存储为另一张表"? 这是否包括创建一个临时表,其实雪花在某种程度上本质上就是这样做的。
你是在什么规模的虚拟仓库上运行的,你是否在query1中对结果进行了排序?
也许在SELECT中添加一个伪列,按它排序,并在你的OFFSET查询中使用它将帮助你限制OFFSET查询中处理的数据量。 我这样说是因为最终的目标是限制你在每个查询中扫描的微分区的数量,所以这是我第一步要做的事情。 如果你能用群集键创建一个临时表,并在你的 "偏移 "逻辑中使用这些列,你应该也很不错。
我希望这能帮到你......Rich