我正在基于PrestoDB的AWS Athena上运行它。我最初的计划是查询过去3个月的数据以分析该数据。但是,即使过去2个小时的查询时间也要花费30多分钟,此时查询将超时。有没有更有效的查询方式?
SELECT column1, dt, column 2
FROM database1
WHERE date_parse(dt, '%Y%m%d%H%i%s') > CAST(now() - interval '1' hour AS timestamp)
日期列以字符串YYYYmmddhhmmss的形式记录
答案 0 :(得分:4)
同样,问题是查询在被过滤的列上应用了一个函数。这是低效率的,因为数据库需要先转换整个列才能对其进行过滤。有人说这个谓词是 SARGable 。
您的主要工作应该是修复数据模型,并将日期存储为date
而不是字符串。
也就是说,您用来表示日期的字符串格式仍然可以使用直接过滤。这个想法是将过滤器值转换为目标字符串格式(而不是将列值转换为日期):
where dt > date_format(now() - interval '1' hour, '%Y%m%d%H%i%s')
答案 1 :(得分:0)
有许多不同的因素会影响Athena执行查询所花费的时间。数据量通常占主导地位,但其他重要因素是数据格式(例如CSV和Parquet之间存在巨大差异)和文件数。与许多其他新数据库情况相比,查询的复杂性通常不是一个重要因素,而且查询非常简单,也不是问题所在(在{{1 }}条件,但是在Athena中这并不是什么大问题,因为过滤是蛮力的,并且与Athena这样的引擎中的IO相比,在每行上应用函数并不是什么大问题。
如果您提供有关文件数量,数据格式等的更多信息,我们可能会更好地为您提供帮助,因为如果没有此类信息,它可能几乎是任何东西。我怀疑您有一个带有成千上万个文件的前缀,这是雅典娜最糟糕的情况。
Athena计划查询时,它将列出表在S3上的位置。 S3的列表操作的页面大小为1000,因此,如果文件多于该雅典娜,则雅典娜将必须顺序列出直到获得完整列表。这不能并行化,而且速度也不很快。
几乎需要不惜一切代价避免在同一前缀中包含1000个以上的文件。如果文件更多,则可以添加前缀(目录),因为Athena会像列出文件系统一样列出S3,并并行化前缀列表。 WHERE
,table-data/a/
,table-data/b/
中的1000个文件比table-data/c/
中的3000个文件好得多。
我之所以怀疑它是很多小文件而不是很多数据,是因为如果有很多数据,您可能会这么说–而很多数据实际上是Athena真正擅长的东西。除非是十亿个微小的文件,否则复制TB级的数据就没有问题。