我有以下查询,显示所选维度的总销售额。Table a
不包含product_name
,这就是为什么我在product_id
上与table b
连接数据的原因。
然而,table b
太大了,我想优化它来扫描更少的数据。
SELECT a.date,
a.hour,
a.category_id,
a.product_id,
b.product_name,
sum(a.sales) AS sales
FROM a
LEFT JOIN b
ON a.product_id = b.product_id
WHERE date(a.date) >= date('2021-01-01')
AND date(B.date) = date('2021-01-01')
GROUP BY 1, 2, 3, 4, 5
你有什么建议吗?有两种方法可以减少Athena需要为给定查询扫描的数据量:
- 确保表是分区的,并且确保查询使用了分区。
- 将数据存储为Parquet或ORC。
这两者可以单独使用,也可以组合使用。最好的结果是通过组合,但有时不方便或不可能。
你的问题没有说表是否分区,但从查询来看,我觉得它们不是-除非date
是分区键。
date
将是一个很好的分区键,如果是,那么您的查询已经很好了。AND date(B.date) = date('2021-01-01')
将把对表b
的扫描限制在一个分区内。但是,如果date
不是分区键,那么Athena将不得不扫描整个表以找到符合条件的行。
b
表的文件是按date
排序的,或者至少是按date
排序的方式创建的,那么Athena将能够查看元数据并跳过不能包含查找日期的文件,因为它超出了该文件的最小/最大值给出的范围。Athena也只需要读取b
表中包含date
列的部分文件,因为这是查询中唯一使用的一个。
如果你用更多关于表模式和数据如何存储的信息来修改你的问题,我可以更详细地回答如何优化。根据现有的信息,我只能给出上述的一般指导。
- 确保b表在日期和product_id上有索引,正如Stu的评论所建议的
- 在SQL上运行一个解释计划(从控制台),看看优化器是否在加入到a之前过滤了b。如果它已经这样做了,你就完成了-步骤3不会有帮助
- 将
From a Left Join b
替换为From a Left Join (Select product_id, product_name from b where date(date) = date('2021-01-01')) b