【问题标题】:full table scan in snowflake when using order by and limit by cluster key使用 order by 和 limit by cluster key 时雪花中的全表扫描
【发布时间】:2022-07-25 18:14:37
【问题描述】:

我有大约 450M 行的 Snowflake 表,该表仅包含 2 个字段,_date 是 DATE 类型,Data 是 VARIANT 类型。集群键是 Date 并且事件平均分布在每一天

Name LINEAR(_DATE) rows bytes automation clustering
DATEDEVENTS LINEAR(_DATE) 444,087,723 129228379136 ON

我正在尝试运行以下简单查询

select *
from datedevents 
order by _DATE
limit 200

snowflake 正在执行全表扫描, 我不能只查询第一天第二天等。因为用例更复杂, 但是为什么雪花不能使用他的集群密钥来高效地执行这个操作并且不扫描所有数据呢?除了第一次约会、第二次约会等,我会一直坚持到他达到 200 人的限制

【问题讨论】:

  • 一个答案可能是您的集群不是 100%,因此需要“其他分区”。这可以通过添加EXPLAINWHERE _date > <minus N days> 进行测试,然后查看将读取多少个分区。并检查 N 的一些值是否为 1,2,7,14
  • 另一个答案可能是分区加载的优化器完全基于 WHERE 子句,您没有,因此所有分区都已加载。同样对于这个假设,如果您知道每天有 X 条消息(例如 10 倍或 15 倍)“只是为了安全”,我将完全设置 N 天的过滤限制。
  • 查看我更新的答案,通过in() 进行修剪来解决

标签: snowflake-cloud-data-platform


【解决方案1】:

用一个很好的修复更新

好的,有一种方法可以通过一个查询进行良好的修剪。

设置:

create or replace transient table test_prune
cluster by (creation_date)
as
select creation_date, body
from temp.public.stackoverflow_posts

慢查询:

select *
from test_prune
order by creation_date
limit 10
-- 10s on a S-WH

快速查询:


select *
from test_prune
where creation_date in (select creation_date from test_prune order by 1 limit 10) 
order by creation_date
limit 10

-- 0.2s on a S-WH

有什么区别,为什么这个in提示更快而不需要在这里单独查询?

好吧,我创建了一个transient 表而不是temp 表。优化器修剪对更多“永久”表的效果更好。


上一个答案

我们需要在这里帮助优化器。我为我的实验创建了一个类似的表:

create or replace temp table test_prune
cluster by (creation_date)
as
select creation_date, body
from temp.public.stackoverflow_posts
order by creation_date

现在让我们对其进行查询:

select *
from test_prune
order by creation_date
limit 10

正如你所说,这需要优化:

我将查询分成两部分得到了最好的结果:

  • 首先创建一个包含您要查找的日期的表格:
create or replace temp table top_dates
as 
select distinct creation_date
from (
    select creation_date 
    from test_prune
    order by creation_date
    limit 10
);  --687ms
  • 那么其他所有查询都可以使用这些结果:
select *
from test_prune
where creation_date in (select creation_date from top_dates)
order by creation_date
limit 10
;  --308ms

通过这种分离,我们可以将原始查询从 7.9s 缩短到 0.5s (0.3+0.25)。

【讨论】:

  • 非常感谢!尽管在幕后看起来他仍然在进行表扫描(尽管它是在小得多的数据上),我猜这对于非常大的表可能会出现问题
  • 哦,所以第一个屏幕截图在 ~1274 个分区表上显示“已扫描的分区:2548 个中的 1227 个”。那是因为它扫描了两次,只有“日期”查询会扫描整个内容,但因为它是柱状且紧凑的,所以速度非常快。然后重扫描被很好地修剪。请报告您的表现。
【解决方案2】:

如果您没有禁用缓存,第一个查询将正常运行,而第二个查询将从仓库缓存中读取,在这种情况下,您将在毫秒内获得结果。第二个查询没有执行任何计算……我对这些结果持怀疑态度。

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2017-05-12
    • 2012-11-22
    • 2023-03-21
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2012-02-13
    相关资源
    最近更新 更多