问题描述
我正在寻找使用sql获取每个分区(a,b)的第一条记录(a,b,c列)的最快方法。表格大约有10、000、000行。
方法1:
SELECT * FROM (
SELECT a,b,c,ROW_NUMBER() OVER ( PARTITION by a,b ORDER BY date DESC) as row_num
FROM T
) WHERE row_num =1
但是它可能在幕后做额外的工作-每个分区只需要第一行。
使用FirsT_VALUE()方法#2。由于FirsT_VALUE()返回表达式 让我们使用一些分隔符将a,b,c打包/连接成单个表达式,例如:
SELECT FirsT_VALUE(a+','+'b'+','+c)
OVER ( PARTITION by a,b ORDER BY date DESC rows unbounded preceding) FROM T
但是在这种情况下,我需要解压缩结果,这是额外的步骤。
使用FirsT_VALUE()方法#3-对a,b重复OVER(...):
SELECT
FirsT_VALUE(a)
OVER ( PARTITION by a,b ORDER BY date DESC rows unbounded preceding),FirsT_VALUE(b)
OVER ( PARTITION by a,c
FROM T
在方法3中,我不知道数据库引擎(Redshift)是否足够聪明以至于只能分区一次
解决方法
这个评论太长了。
第一个查询与其他两个查询不同。第一个仅返回每组一行。其他两个返回与原始查询相同的行。
您应该使用满足您需求的版本,我认为这是第一个。如果将select distinct
或group by
添加到其他查询中,则可能会增加开销,从而使它们变慢-但您可以测试数据以查看是否正确。
您的直觉是正确的,即第一个查询做了不必要的工作。在完全支持索引的数据库中,相关子查询通常更快。但是,我不认为Redshift会是这种情况。