在Tez上使用Hive对此视图运行此查询会导致全表扫描,即使regionid和id上有分区。Cloudera Impala中的此查询需要0.6秒才能完成,在Tez中使用Hortonworks数据平台和Hive需要800秒。我得出的结论是,在Hive on Tez中,使用窗口函数可以防止谓词向下推到内部选择,从而导致完整的表扫描。
CREATE VIEW latestposition AS
WITH t1 AS (
SELECT *, ROW_NUMBER() OVER ( PARTITION BY regionid, id, deviceid order by ts desc) AS rownos FROM positions
)
SELECT *
FROM t1
WHERE rownos = 1;
SELECT * FROM latestposition WHERE regionid='1d6a0be1-6366-4692-9597-ebd5cd0f01d1' and id=1422792010 and deviceid='6c5d1a30-2331-448b-a726-a380d6b3a432';
我试着使用MAX函数将这个表连接到它自己,以获得最新的记录,它可以工作,并在几秒钟内完成,但对于我的用例来说,它仍然太慢了。此外,如果我删除窗口函数,谓词会被按下,这将在几毫秒内返回。
如果有人有任何想法,我们将不胜感激。
对于任何感兴趣的人,我在Hortonworks社区论坛上发布了这个问题。那里的好人在Hive Jira上提出了一个关于这个问题的错误,并正在积极解决。
https://community.hortonworks.com/questions/8880/hive-on-tez-pushdown-predicate-doesnt-work-in-part.html
https://issues.apache.org/jira/browse/HIVE-12808
这是预期行为。为了避免全表扫描,您必须应用这样的where条件(使用视图时无法应用)。这是大多数数据库的限制。分析函数应该在数据过滤后应用,因为它将在内部创建临时表。
WITH t1 AS (
SELECT *, ROW_NUMBER() OVER ( PARTITION BY regionid, id, deviceid order by ts desc) AS rownos FROM positions **<where condition>**
)
SELECT *
FROM t1
WHERE rownos = 1;