【发布时间】:2020-06-19 10:41:05
【问题描述】:
我目前正在使用 Snowflake 中的数据库,但我遇到了性能问题。
在我的查询中,我需要从包含其他表的外键的 MAIN_TABLE 中检索 100 行数据。 MAIN_TABLE 大小介于 50K-300K 行之间。
这个 MAIN_TABLE 包含 NUMBER(38,0) 类型的 ids(外键),并且这些字段/列的描述是通过简单的 INNER JOIN 从其他表中检索的。
辅助表(table_one、table_two...)非常小,所有的行数都少于 20 行,除了一个有大约 1500 行(仍然非常小)
问题是:
如下所示,运行查询平均需要 1.7 秒才能完成。 如果我删除所有 DESC 字段(使用 INNER JOIN 检索)和所有 INNER JOIN,则查询平均需要 300 毫秒才能完成。
我的同行实施的当前解决方案:
他们已经缓存了我们应用程序中所有辅助表的信息(用Java制作,但这无关紧要)。对于大约 80% 的情况(请参阅下面的查询),我们不需要按 DESCription 过滤,这是可行的,但在其他 20% 的情况下,我们仍然需要执行 INNER JOIN。
缩小解决方案:
不是一个糟糕的解决方案,但它有两个问题:
- (还不错)它使我们的代码库膨胀,基本上是用 Java 制作的“JOIN”
- 在我们需要按 DESCriptions 过滤的 20% 的时间里,我们仍然需要执行 INNER JOIN,因此我们仍然存在性能问题。
想到的一种可能性是在 SF 中缓存这些表,但我还没有找到一种直接的方法来做到这一点。也许有一种优化查询的方法,但我还不明白 Snowflake 内部是如何工作的,据我所知它不使用索引,至少不像其他平台那样。
那么,有没有办法针对 100% 的情况优化 SF 中的查询?
SELECT
main_table.ONE_ID,
main_table.TWO_ID,
main_table.THREE_ID,
main_table.FOUR_ID,
main_table.FIVE_ID,
main_table.SIX_ID,
main_table.SEVEN_ID,
field_one.ONE_DESC,
field_two.TWO_DESC,
field_three.THREE_DESC,
field_four.FOUR_DESC,
field_five.FIVE_DESC,
field_six.SIX_DESC,
field_seven.SEVEN_DESC
FROM
SOME_DATABASE.MAIN_TABLE AS main_table
INNER JOIN SOME_DATABASE.TABLE_ONE AS table_one ON main_table.field_one_id = table_one .ONE_ID
INNER JOIN SOME_DATABASE.TABLE_TWO AS table_two ON main_table.field_two_id = table_two .TWO_ID
INNER JOIN SOME_DATABASE.TABLE_THREE AS table_tree ON main_table.field_tree_id = table_tree .THREE_ID
INNER JOIN SOME_DATABASE.TABLE_FOUR AS table_four ON main_table.field_four_id = table_four .FOUR_ID
INNER JOIN SOME_DATABASE.TABLE_FIVE AS table_five ON main_table.field_five_id = table_five .FIVE_ID
INNER JOIN SOME_DATABASE.TABLE_SIX AS table_six ON main_table.field_six_id = table_six .SIX_ID
INNER JOIN SOME_DATABASE.TABLE_SEVEN AS table_seven ON main_table.field_seven_id = table_seven .SEVEN_ID
WHERE
main_table.ONE_ID IN (25, 26)
AND main_table.TWO_ID IN (10, 12)
AND main_table.THREE_ID IN (1, 2, 3)
AND main_table.FOUR_ID IN (2, 3)
AND main_table.FIVE_ID IN (3)
AND main_table.SEVEN_ID IN (1)
-- The following WHERE clauses are present in about 20% of the queries
AND table_one.ONE_DESC,
AND table_two.TWO_DESC,
AND table_three.THREE_DESC,
ORDER BY
main_table.ONE_ID,
main_table.TWO_ID,
main_table.THREE_ID
LIMIT
100 OFFSET 0
小更新:
我一直在尝试使用 WITH 子句,同时包装 id 和描述,但似乎没有改进
【问题讨论】:
-
当您运行这些测试时,您是否看到正在使用大量缓存?查询配置文件中每个表的修剪是什么?您是否尝试过使用事实中的 DESC 字段创建一个新表并进行比较?
-
您是否检查过查询配置文件以了解最耗时的内容?您可能使用 CTE 走在正确的轨道上,应该首先将配置文件中具有长进程的小表/联接取出到 CTE 的它们自己的部分中。
标签: sql snowflake-cloud-data-platform